Skip to content

Commit

Permalink
Better coin test coverage (#1062)
Browse files Browse the repository at this point in the history
## Description

Added WETH approval in the ZoraFactoryImpl contract and introduced new test cases for secondary rewards claiming and WETH-related functionality. The changes include validation for WETH tick parameters and proper handling of ETH/WETH transactions.

## Motivation and Context

Ensures proper token approvals for WETH transactions and adds comprehensive testing coverage for secondary rewards claiming scenarios. This improves the robustness of the protocol's token handling mechanisms.

## Does this change the ABI/API?

- [ ] This changes the ABI/API

## What tests did you add/modify to account for these changes

- Added test for selling ETH directly and claiming secondary rewards
- Added test for selling ETH directly with ETH push functionality
- Added validation test for invalid WETH tick parameters
- Added test for WETH deployment scenarios
- Added test to verify factory implementation address

## Types of changes

- [x] Bug fix (non-breaking change which fixes an issue)
- [ ] New module / feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)

## Checklist:

- [x] My code follows the code style of this project.
- [ ] My change requires a change to the documentation.
- [ ] I have updated the documentation accordingly.
- [ ] I added a changeset to account for this change

## Reviewer Checklist:

- [ ] My review includes a symposis of the changes and potential issues
- [ ] The code style is enforced
- [ ] There are no risky / concerning changes / additions to the PR
  • Loading branch information
iainnash authored Feb 21, 2025
1 parent eb061bd commit a5960de
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 1 deletion.
113 changes: 113 additions & 0 deletions packages/coins/test/Coin.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
pragma solidity ^0.8.13;

import "./utils/BaseTest.sol";
import {ISwapRouter} from "../src/interfaces/ISwapRouter.sol";

contract CoinTest is BaseTest {
function setUp() public override {
Expand Down Expand Up @@ -211,6 +212,82 @@ contract CoinTest is BaseTest {
assertGe(coin.balanceOf(users.coinRecipient), amountOut, "coinRecipient coin balance");
}

function test_sell_for_eth_direct_and_claim_secondary() public {
vm.deal(users.buyer, 1 ether);

vm.prank(users.buyer);
weth.deposit{value: 100_000}();

vm.prank(users.buyer);
weth.approve(address(swapRouter), 100_000);

// Set up the swap parameters
ISwapRouter.ExactInputSingleParams memory params = ISwapRouter.ExactInputSingleParams({
tokenIn: WETH_ADDRESS,
tokenOut: address(coin),
fee: LP_FEE,
recipient: address(users.buyer),
amountIn: 100_000,
amountOutMinimum: 0,
sqrtPriceLimitX96: 0
});

// Execute the swap
vm.prank(users.buyer);
uint256 amountOut = ISwapRouter(swapRouter).exactInputSingle(params);

assertEq(coin.balanceOf(users.buyer), 44294392087151, "buyer coin balance");
assertEq(amountOut, 44294392087151);
assertGt(users.buyer.balance, 0, "seller eth balance");

// now we have unclaimed secondary rewards to claim
vm.prank(users.buyer);

// don't push ETH
coin.claimSecondaryRewards(false);
assertEq(protocolRewards.balanceOf(users.creator), 499);
assertEq(protocolRewards.balanceOf(users.platformReferrer), 249);
assertEq(protocolRewards.balanceOf(users.feeRecipient), 251);
}

function test_sell_for_eth_direct_and_claim_secondary_push_eth() public {
vm.deal(users.buyer, 1 ether);

vm.prank(users.buyer);
weth.deposit{value: 100_000}();

vm.prank(users.buyer);
weth.approve(address(swapRouter), 100_000);

// Set up the swap parameters
ISwapRouter.ExactInputSingleParams memory params = ISwapRouter.ExactInputSingleParams({
tokenIn: WETH_ADDRESS,
tokenOut: address(coin),
fee: LP_FEE,
recipient: address(users.buyer),
amountIn: 100_000,
amountOutMinimum: 0,
sqrtPriceLimitX96: 0
});

// Execute the swap
vm.prank(users.buyer);
uint256 amountOut = ISwapRouter(swapRouter).exactInputSingle(params);

assertEq(coin.balanceOf(users.buyer), 44294392087151, "buyer coin balance");
assertEq(amountOut, 44294392087151);
assertGt(users.buyer.balance, 0, "seller eth balance");

// Now we have unclaimed secondary rewards to claim
vm.prank(users.buyer);

uint256 initialBalance = users.creator.balance;

// Push ETH
coin.claimSecondaryRewards(true);
assertEq(users.creator.balance - initialBalance, 499);
}

function test_sell_for_eth() public {
vm.deal(users.buyer, 1 ether);
vm.prank(users.buyer);
Expand Down Expand Up @@ -373,6 +450,42 @@ contract CoinTest is BaseTest {
assertGt(protocolRewards.balanceOf(users.feeRecipient), expectedFees.platformReferrer, "feeRecipient eth balance");
}

function test_invalid_weth_tick() public {
address[] memory owners = new address[](1);
owners[0] = users.creator;

vm.expectRevert(ICoin.InvalidWethLowerTick.selector);
(address newCoinAddr, ) = factory.deploy(
users.creator,
owners,
"https://test.com",
"Test Token",
"TEST",
users.platformReferrer,
address(weth),
20,
0
);
}

function test_invalid_currency_tick() public {
address[] memory owners = new address[](1);
owners[0] = users.creator;

vm.expectRevert(ICoin.InvalidCurrencyLowerTick.selector);
(address newCoinAddr, ) = factory.deploy(
users.creator,
owners,
"https://test.com",
"Test Token",
"TEST",
users.platformReferrer,
address(0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913),
20,
0
);
}

function test_default_order_referrer() public {
vm.deal(users.buyer, 1 ether);
vm.prank(users.buyer);
Expand Down
33 changes: 33 additions & 0 deletions packages/coins/test/Factory.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,35 @@ contract FactoryTest is BaseTest {
console.log("BUYER_COIN_BALANCE ", coin.balanceOf(users.creator) - 10_000_000e18);
}

function test_deploy_with_weth(uint256 initialOrderSize) public {
vm.assume(initialOrderSize > MIN_ORDER_SIZE);
vm.assume(initialOrderSize < 10 ether);

address[] memory owners = new address[](1);
owners[0] = users.creator;

vm.deal(users.creator, initialOrderSize);

vm.startPrank(users.creator);
weth.deposit{value: initialOrderSize}();

weth.approve(address(factory), type(uint256).max);

// Expect this to revert because WETH needs to be sent with msg.value.
vm.expectRevert();
factory.deploy(
users.creator,
owners,
"https://test2.com",
"Test2 Token",
"TEST2",
users.platformReferrer,
address(weth),
LP_TICK_LOWER_WETH,
initialOrderSize
);
}

function test_deploy_with_one_eth() public {
address[] memory owners = new address[](1);
owners[0] = users.creator;
Expand Down Expand Up @@ -272,6 +301,10 @@ contract FactoryTest is BaseTest {
assertEq(factory.implementation(), address(newImpl), "implementation");
}

function test_implementation_address() public {
assertEq(factory.implementation(), address(factoryImpl));
}

function test_revert_invalid_upgrade_impl() public {
address newImpl = address(this);

Expand Down
2 changes: 1 addition & 1 deletion packages/coins/test/utils/BaseTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ contract BaseTest is Test, CoinConstants {
IUniswapV3Pool internal pool;

function setUp() public virtual {
forkId = vm.createSelectFork("https://mainnet.base.org", 21179722);
forkId = vm.createSelectFork("base", 21179722);

weth = IWETH(WETH_ADDRESS);
usdc = IERC20Metadata(USDC_ADDRESS);
Expand Down

0 comments on commit a5960de

Please sign in to comment.