From 6b41bd67a286e2efe5c5bd7305586876b1e8aeb3 Mon Sep 17 00:00:00 2001 From: robertu <4065233+robertu7@users.noreply.github.com> Date: Mon, 3 Jun 2024 20:22:41 +0800 Subject: [PATCH] feat(curation: add tests for sweep --- .gas-snapshot | 27 ++++-- src/test/Curation/Vault.t.sol | 162 ++++++++++++++++++++++++++++++++++ 2 files changed, 180 insertions(+), 9 deletions(-) diff --git a/.gas-snapshot b/.gas-snapshot index 35da679..c075f2b 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -175,12 +175,21 @@ TheSpaceTest:testTotalSupply() (gas: 7613) TheSpaceTest:testUpgradeTo() (gas: 3215197) TheSpaceTest:testWithdrawTreasury() (gas: 352672) TheSpaceTest:testWithdrawUBI() (gas: 375819) -VaultTest:testCannotErc20TokenDepositZeroAmount() (gas: 15881) -VaultTest:testCannotNativeTokenClaimAlreadyClaimed() (gas: 154235) -VaultTest:testCannotNativeTokenClaimExpired() (gas: 49765) -VaultTest:testCannotNativeTokenClaimInvalidSignature() (gas: 60595) -VaultTest:testCannotNativeTokenClaimZeroBalance() (gas: 20155) -VaultTest:testCannotNativeTokenDepositZeroAmount() (gas: 13631) -VaultTest:testErc20TokenDeposit() (gas: 91953) -VaultTest:testNativeTokenClaim() (gas: 142834) -VaultTest:testNativeTokenDeposit() (gas: 59588) \ No newline at end of file +VaultTest:testCannotErc20TokenClaimAlreadyClaimed() (gas: 181263) +VaultTest:testCannotErc20TokenClaimExpired() (gas: 82592) +VaultTest:testCannotErc20TokenClaimInvalidSignature() (gas: 93550) +VaultTest:testCannotErc20TokenClaimZeroBalance() (gas: 22674) +VaultTest:testCannotErc20TokenDepositZeroAmount() (gas: 15938) +VaultTest:testCannotNativeTokenClaimAlreadyClaimed() (gas: 154193) +VaultTest:testCannotNativeTokenClaimExpired() (gas: 49834) +VaultTest:testCannotNativeTokenClaimInvalidSignature() (gas: 60597) +VaultTest:testCannotNativeTokenClaimZeroBalance() (gas: 20179) +VaultTest:testCannotNativeTokenDepositZeroAmount() (gas: 13621) +VaultTest:testCannotSetSignerByAttacker() (gas: 13226) +VaultTest:testErc20TokenClaim() (gas: 150708) +VaultTest:testErc20TokenDeposit() (gas: 92032) +VaultTest:testErc20TokenSweep() (gas: 101388) +VaultTest:testNativeTokenClaim() (gas: 142804) +VaultTest:testNativeTokenDeposit() (gas: 59633) +VaultTest:testNativeTokenSweep() (gas: 93006) +VaultTest:testSetSigner() (gas: 21536) \ No newline at end of file diff --git a/src/test/Curation/Vault.t.sol b/src/test/Curation/Vault.t.sol index 98ea0a3..181285b 100644 --- a/src/test/Curation/Vault.t.sol +++ b/src/test/Curation/Vault.t.sol @@ -222,4 +222,166 @@ contract VaultTest is Test { vm.prank(CREATOR); vault.claim(_vaultId, CREATOR, _expiredAt, _v, _r, _s); } + + /** + * Claim: ERC-20 Token + */ + function testErc20TokenClaim() public { + uint256 _amount = 100; + bytes32 _vaultId = keccak256(abi.encodePacked(CREATOR)); + uint256 _creatorBalance = usdt.balanceOf(CREATOR); + + uint256 _expiredAt = block.timestamp + 1 days; + bytes32 _digest = keccak256( + abi.encodePacked(_vaultId, address(usdt), CREATOR, _expiredAt, block.chainid, address(vault)) + ).toEthSignedMessageHash(); + (uint8 _v, bytes32 _r, bytes32 _s) = vm.sign(DEPLOYER_PK, _digest); + + depositERC20(_amount, _vaultId); + + vm.expectEmit(true, true, true, true); + emit IVault.Claimed(_vaultId, address(usdt), CREATOR, _amount); + + vm.prank(CREATOR); + vault.claim(_vaultId, address(usdt), CREATOR, _expiredAt, _v, _r, _s); + + assertEq(usdt.balanceOf(CREATOR), _creatorBalance + _amount); + assertEq(vault.erc20Balances(_vaultId, address(usdt)), _amount); + assertEq(vault.erc20Claimed(_vaultId, address(usdt)), _amount); + assertEq(vault.available(_vaultId, address(usdt)), 0); + } + + function testCannotErc20TokenClaimZeroBalance() public { + bytes32 _vaultId = keccak256(abi.encodePacked(CREATOR)); + uint256 _expiredAt = block.timestamp + 1 days; + bytes32 _digest = keccak256( + abi.encodePacked(_vaultId, address(usdt), CREATOR, _expiredAt, block.chainid, address(vault)) + ).toEthSignedMessageHash(); + (uint8 _v, bytes32 _r, bytes32 _s) = vm.sign(DEPLOYER_PK, _digest); + + vm.expectRevert(abi.encodeWithSignature("ZeroBalance()")); + vm.prank(CREATOR); + vault.claim(_vaultId, address(usdt), CREATOR, _expiredAt, _v, _r, _s); + } + + function testCannotErc20TokenClaimExpired() public { + uint256 _amount = 100; + bytes32 _vaultId = keccak256(abi.encodePacked(CREATOR)); + + uint256 _expiredAt = block.timestamp - 1; + bytes32 _digest = keccak256( + abi.encodePacked(_vaultId, address(usdt), CREATOR, _expiredAt, block.chainid, address(vault)) + ).toEthSignedMessageHash(); + (uint8 _v, bytes32 _r, bytes32 _s) = vm.sign(DEPLOYER_PK, _digest); + + depositERC20(_amount, _vaultId); + + vm.expectRevert(abi.encodeWithSignature("ClaimExpired()")); + vm.prank(CREATOR); + vault.claim(_vaultId, address(usdt), CREATOR, _expiredAt, _v, _r, _s); + } + + function testCannotErc20TokenClaimInvalidSignature() public { + uint256 _amount = 100; + bytes32 _vaultId = keccak256(abi.encodePacked(CREATOR)); + + uint256 _expiredAt = block.timestamp + 1 days; + bytes32 _digest = keccak256( + abi.encodePacked(_vaultId, address(usdt), CREATOR, _expiredAt, block.chainid, address(vault)) + ).toEthSignedMessageHash(); + (uint8 _v, bytes32 _r, bytes32 _s) = vm.sign(DEPLOYER_PK, _digest); + + depositERC20(_amount, _vaultId); + + vm.expectRevert(abi.encodeWithSignature("InvalidSignature()")); + vm.prank(ATTACKER); + vault.claim(_vaultId, address(usdt), ATTACKER, _expiredAt, _v, _r, _s); + } + + function testCannotErc20TokenClaimAlreadyClaimed() public { + uint256 _amount = 100; + bytes32 _vaultId = keccak256(abi.encodePacked(CREATOR)); + + uint256 _expiredAt = block.timestamp + 1 days; + bytes32 _digest = keccak256( + abi.encodePacked(_vaultId, address(usdt), CREATOR, _expiredAt, block.chainid, address(vault)) + ).toEthSignedMessageHash(); + (uint8 _v, bytes32 _r, bytes32 _s) = vm.sign(DEPLOYER_PK, _digest); + + depositERC20(_amount, _vaultId); + + vm.expectEmit(true, true, true, true); + emit IVault.Claimed(_vaultId, address(usdt), CREATOR, _amount); + + vm.prank(CREATOR); + vault.claim(_vaultId, address(usdt), CREATOR, _expiredAt, _v, _r, _s); + + depositERC20(_amount, _vaultId); + + vm.expectRevert(abi.encodeWithSignature("AlreadyClaimed()")); + vm.prank(CREATOR); + vault.claim(_vaultId, address(usdt), CREATOR, _expiredAt, _v, _r, _s); + } + + /** + * Sweep + */ + function testNativeTokenSweep() public { + uint256 _amount = 1 ether; + bytes32 _vaultId = keccak256(abi.encodePacked(CREATOR)); + uint256 _ownerBalance = OWNER.balance; + + depositETH(_amount, _vaultId); + + vm.expectEmit(true, true, true, true); + emit IVault.Swept(OWNER, _amount); + + vm.prank(OWNER); + vault.sweep(OWNER); + + assertEq(OWNER.balance, _ownerBalance + _amount); + assertEq(vault.balances(_vaultId), _amount); + assertEq(vault.claimed(_vaultId), 0); + assertEq(vault.available(_vaultId), _amount); + } + + function testErc20TokenSweep() public { + uint256 _amount = 100; + bytes32 _vaultId = keccak256(abi.encodePacked(CREATOR)); + uint256 _ownerBalance = usdt.balanceOf(OWNER); + + depositERC20(_amount, _vaultId); + + vm.expectEmit(true, true, true, true); + emit IVault.Swept(address(usdt), OWNER, _amount); + + vm.prank(OWNER); + vault.sweep(address(usdt), OWNER); + + assertEq(usdt.balanceOf(OWNER), _ownerBalance + _amount); + assertEq(vault.erc20Balances(_vaultId, address(usdt)), _amount); + assertEq(vault.erc20Claimed(_vaultId, address(usdt)), 0); + assertEq(vault.available(_vaultId, address(usdt)), _amount); + } + + function testSetSigner() public { + address _signer = address(0x1234567890123456789012345678901234567890); + + vm.expectEmit(true, true, true, true); + emit IVault.SignerChanged(_signer); + + vm.prank(OWNER); + vault.setSigner(_signer); + + assertEq(vault.signer(), _signer); + } + + function testCannotSetSignerByAttacker() public { + address _signer = address(0x1234567890123456789012345678901234567890); + + vm.expectRevert("Ownable: caller is not the owner"); + + vm.prank(ATTACKER); + vault.setSigner(_signer); + } }