From 0f97c5a6d1fefcabf08ab60b4b547ad6c94edbe7 Mon Sep 17 00:00:00 2001 From: Ruslan Kasheparov <55411970+RuslanProgrammer@users.noreply.github.com> Date: Mon, 8 Jan 2024 09:56:35 +0100 Subject: [PATCH] Merge events into dev (#8) * Add events to contracts (#7) * added events * added tests for events * moved events to specific functions --- contracts/Distribution.sol | 20 ++++++++- contracts/L2MessageReceiver.sol | 6 ++- contracts/L2TokenReceiver.sol | 8 +++- contracts/interfaces/IDistribution.sol | 43 +++++++++++++++++++ contracts/interfaces/IL2MessageReceiver.sol | 32 +++++++++++--- contracts/interfaces/IL2TokenReceiver.sol | 34 +++++++++++++++ test/Distribution.test.ts | 46 +++++++++++++++++---- test/fork/L2TokenReceiver.fork.test.ts | 22 +++++----- 8 files changed, 179 insertions(+), 32 deletions(-) diff --git a/contracts/Distribution.sol b/contracts/Distribution.sol index bb7a71b..d82910f 100644 --- a/contracts/Distribution.sol +++ b/contracts/Distribution.sol @@ -70,6 +70,8 @@ contract Distribution is IDistribution, OwnableUpgradeable, UUPSUpgradeable { _validatePool(pool_); pools.push(pool_); + + emit PoolCreated(pools.length - 1, pool_); } function editPool(uint256 poolId_, Pool calldata pool_) external onlyOwner poolExists(poolId_) { @@ -84,6 +86,8 @@ contract Distribution is IDistribution, OwnableUpgradeable, UUPSUpgradeable { poolData.lastUpdate = uint128(block.timestamp); pools[poolId_] = pool_; + + emit PoolEdited(poolId_, pool_); } function getPeriodReward(uint256 poolId_, uint128 startTime_, uint128 endTime_) public view returns (uint256) { @@ -165,6 +169,8 @@ contract Distribution is IDistribution, OwnableUpgradeable, UUPSUpgradeable { // Transfer rewards L1Sender(l1Sender).sendMintMessage{value: msg.value}(user_, pendingRewards_, _msgSender()); + + emit UserClaimed(poolId_, user_, pendingRewards_); } function withdraw(uint256 poolId_, uint256 amount_) external poolExists(poolId_) poolPublic(poolId_) { @@ -212,6 +218,8 @@ contract Distribution is IDistribution, OwnableUpgradeable, UUPSUpgradeable { // Update user data userData.rate = currentPoolRate_; userData.deposited += amount_; + + emit UserStaked(poolId_, user_, amount_); } function _withdraw(address user_, uint256 poolId_, uint256 amount_, uint256 currentPoolRate_) internal { @@ -265,6 +273,8 @@ contract Distribution is IDistribution, OwnableUpgradeable, UUPSUpgradeable { IERC20(depositToken).safeTransfer(user_, amount_); } + + emit UserWithdrawn(poolId_, user_, amount_); } function _getCurrentUserReward( @@ -309,13 +319,19 @@ contract Distribution is IDistribution, OwnableUpgradeable, UUPSUpgradeable { uint256 gasLimit_, uint256 maxFeePerGas_, uint256 maxSubmissionCost_ - ) external payable onlyOwner returns (bytes memory) { + ) external payable onlyOwner returns (bytes memory bridgeMessageId_) { uint256 overplus_ = overplus(); require(overplus_ > 0, "DS: overplus is zero"); IERC20(depositToken).safeTransfer(l1Sender, overplus_); - return L1Sender(l1Sender).sendDepositToken{value: msg.value}(gasLimit_, maxFeePerGas_, maxSubmissionCost_); + bridgeMessageId_ = L1Sender(l1Sender).sendDepositToken{value: msg.value}( + gasLimit_, + maxFeePerGas_, + maxSubmissionCost_ + ); + + emit OverplusBridged(overplus_, bridgeMessageId_); } /**********************************************************************************************/ diff --git a/contracts/L2MessageReceiver.sol b/contracts/L2MessageReceiver.sol index 446762d..8ad113c 100644 --- a/contracts/L2MessageReceiver.sol +++ b/contracts/L2MessageReceiver.sol @@ -65,7 +65,7 @@ contract L2MessageReceiver is ILayerZeroReceiver, IL2MessageReceiver, OwnableUpg delete failedMessages[senderChainId_][senderAndReceiverAddresses_][nonce_]; - emit RetryMessageSuccess(senderChainId_, senderAndReceiverAddresses_, nonce_, payloadHash_); + emit RetryMessageSuccess(senderChainId_, senderAndReceiverAddresses_, nonce_, payload_); } function _blockingLzReceive( @@ -81,7 +81,9 @@ contract L2MessageReceiver is ILayerZeroReceiver, IL2MessageReceiver, OwnableUpg nonce_, payload_ ) - {} catch (bytes memory reason_) { + { + emit MessageSuccess(senderChainId_, senderAndReceiverAddresses_, nonce_, payload_); + } catch (bytes memory reason_) { failedMessages[senderChainId_][senderAndReceiverAddresses_][nonce_] = keccak256(payload_); emit MessageFailed(senderChainId_, senderAndReceiverAddresses_, nonce_, payload_, reason_); diff --git a/contracts/L2TokenReceiver.sol b/contracts/L2TokenReceiver.sol index e836a9c..441372d 100644 --- a/contracts/L2TokenReceiver.sol +++ b/contracts/L2TokenReceiver.sol @@ -49,7 +49,7 @@ contract L2TokenReceiver is IL2TokenReceiver, ERC165, OwnableUpgradeable, UUPSUp _editParams(newParams_); } - function swap(uint256 amountIn_, uint256 amountOutMinimum_) external onlyOwner returns (uint256) { + function swap(uint256 amountIn_, uint256 amountOutMinimum_) external onlyOwner returns (uint256 amountOut_) { SwapParams memory params_ = params; ISwapRouter.ExactInputSingleParams memory swapParams_ = ISwapRouter.ExactInputSingleParams({ @@ -63,7 +63,9 @@ contract L2TokenReceiver is IL2TokenReceiver, ERC165, OwnableUpgradeable, UUPSUp sqrtPriceLimitX96: params_.sqrtPriceLimitX96 }); - return ISwapRouter(router).exactInputSingle(swapParams_); + amountOut_ = ISwapRouter(router).exactInputSingle(swapParams_); + + emit TokensSwapped(params_.tokenIn, params_.tokenOut, amountIn_, amountOut_, amountOutMinimum_); } function increaseLiquidityCurrentRange( @@ -106,6 +108,8 @@ contract L2TokenReceiver is IL2TokenReceiver, ERC165, OwnableUpgradeable, UUPSUp (liquidity_, amount0_, amount1_) = INonfungiblePositionManager(nonfungiblePositionManager).increaseLiquidity( params_ ); + + emit LiquidityIncreased(tokenId_, amount0_, amount1_, liquidity_, amountMin0_, amountMin1_); } function _editParams(SwapParams memory newParams_) internal { diff --git a/contracts/interfaces/IDistribution.sol b/contracts/interfaces/IDistribution.sol index 9920536..963b0ed 100644 --- a/contracts/interfaces/IDistribution.sol +++ b/contracts/interfaces/IDistribution.sol @@ -52,6 +52,49 @@ interface IDistribution { uint256 pendingRewards; } + /** + * The event that is emitted when the pool is created. + * @param poolId The pool's id. + * @param pool The pool's data. + */ + event PoolCreated(uint256 indexed poolId, Pool pool); + + /** + * The event that is emitted when the pool is edited. + * @param poolId The pool's id. + * @param pool The pool's data. + */ + event PoolEdited(uint256 indexed poolId, Pool pool); + + /** + * The event that is emitted when the user stakes tokens in the pool. + * @param poolId The pool's id. + * @param user The user's address. + * @param amount The amount of tokens. + */ + event UserStaked(uint256 indexed poolId, address indexed user, uint256 amount); + + /** + * The event that is emitted when the user claims rewards from the pool. + * @param poolId The pool's id. + * @param user The user's address. + * @param amount The amount of tokens. + */ + event UserClaimed(uint256 indexed poolId, address indexed user, uint256 amount); + + /** + * The event that is emitted when the user withdraws tokens from the pool. + * @param poolId The pool's id. + * @param user The user's address. + * @param amount The amount of tokens. + */ + event UserWithdrawn(uint256 indexed poolId, address indexed user, uint256 amount); + + /** + * The event that is emitted when the overplus of the deposit tokens is bridged. + */ + event OverplusBridged(uint256 amount, bytes uniqueId); + /** * The function to initialize the contract. * @param depositToken_ The address of deposit token. diff --git a/contracts/interfaces/IL2MessageReceiver.sol b/contracts/interfaces/IL2MessageReceiver.sol index fcc7aac..3dd3668 100644 --- a/contracts/interfaces/IL2MessageReceiver.sol +++ b/contracts/interfaces/IL2MessageReceiver.sol @@ -4,6 +4,23 @@ pragma solidity ^0.8.20; import {ILayerZeroReceiver} from "@layerzerolabs/lz-evm-sdk-v1-0.7/contracts/interfaces/ILayerZeroReceiver.sol"; interface IL2MessageReceiver is ILayerZeroReceiver { + /** + * The event that is emitted when the message is received. + * @param senderChainId The source endpoint identifier. + * @param senderAndReceiverAddresses The source sending contract address from the source chain. + * @param nonce The ordered message nonce. + * @param payload The signed payload is the UA bytes has encoded to be sent. + */ + event MessageSuccess(uint16 senderChainId, bytes senderAndReceiverAddresses, uint64 nonce, bytes payload); + + /** + * The event that is emitted when the message is failed. + * @param senderChainId The source endpoint identifier. + * @param senderAndReceiverAddresses The source sending contract address from the source chain. + * @param nonce The ordered message nonce. + * @param payload The signed payload is the UA bytes has encoded to be sent. + * @param reason The reason of failure. + */ event MessageFailed( uint16 senderChainId, bytes senderAndReceiverAddresses, @@ -11,12 +28,15 @@ interface IL2MessageReceiver is ILayerZeroReceiver { bytes payload, bytes reason ); - event RetryMessageSuccess( - uint16 senderChainId, - bytes senderAndReceiverAddresses, - uint64 nonce, - bytes32 payloadHash - ); + + /** + * The event that is emitted when the message is retried. + * @param senderChainId The source endpoint identifier. + * @param senderAndReceiverAddresses The source sending contract address from the source chain. + * @param nonce The ordered message nonce. + * @param payload The signed payload is the UA bytes has encoded to be sent. + */ + event RetryMessageSuccess(uint16 senderChainId, bytes senderAndReceiverAddresses, uint64 nonce, bytes payload); /** * The structure that stores the config data. diff --git a/contracts/interfaces/IL2TokenReceiver.sol b/contracts/interfaces/IL2TokenReceiver.sol index a047bc2..8bad575 100644 --- a/contracts/interfaces/IL2TokenReceiver.sol +++ b/contracts/interfaces/IL2TokenReceiver.sol @@ -21,6 +21,40 @@ interface IL2TokenReceiver is IERC165 { uint160 sqrtPriceLimitX96; } + /** + * The event that is emitted when the swap is executed. + * @param tokenIn The address of the token to swap from. + * @param tokenOut The address of the token to swap to. + * @param amountIn The amount of tokens to swap. + * @param amountOut The amount of tokens received. + * @param amountOutMinimum The minimum amount of tokens to receive. + */ + event TokensSwapped( + address indexed tokenIn, + address indexed tokenOut, + uint256 amountIn, + uint256 amountOut, + uint256 amountOutMinimum + ); + + /** + * The event that is emitted when the liquidity is increased. + * @param tokenId The ID of the position. + * @param amount0 The amount of token0 added. + * @param amount1 The amount of token1 added. + * @param liquidity The amount of liquidity added. + * @param amount0Min The minimum amount of token0 to add. + * @param amount1Min The minimum amount of token1 to add. + */ + event LiquidityIncreased( + uint256 indexed tokenId, + uint256 amount0, + uint256 amount1, + uint256 liquidity, + uint256 amount0Min, + uint256 amount1Min + ); + /** * The function to edit the swap params. * @param params_ The new swap params. diff --git a/test/Distribution.test.ts b/test/Distribution.test.ts index b9b92bd..160cc75 100644 --- a/test/Distribution.test.ts +++ b/test/Distribution.test.ts @@ -253,7 +253,8 @@ describe('Distribution', () => { it('should create pool with correct data', async () => { const pool = getDefaultPool(); - await distribution.createPool(pool); + const tx = await distribution.createPool(pool); + await expect(tx).to.emit(distribution, 'PoolCreated'); const poolData: IDistribution.PoolStruct = await distribution.pools(0); expect(_comparePoolStructs(pool, poolData)).to.be.true; @@ -300,6 +301,24 @@ describe('Distribution', () => { await distribution.createPool(getDefaultPool()); }); + it('should edit pool with correct data', async () => { + const newPool = { + ...defaultPool, + payoutStart: 10 * oneDay, + decreaseInterval: 10 * oneDay, + withdrawLockPeriod: 10 * oneDay, + initialReward: wei(111), + rewardDecrease: wei(222), + minimalStake: wei(333), + }; + + const tx = await distribution.editPool(poolId, newPool); + await expect(tx).to.emit(distribution, 'PoolEdited'); + + const poolData: IDistribution.PoolStruct = await distribution.pools(poolId); + expect(_comparePoolStructs(newPool, poolData)).to.be.true; + }); + it('should revert if try to change pool type', async () => { const newPool = { ...defaultPool, @@ -346,7 +365,9 @@ describe('Distribution', () => { let userData; setNextTime(oneHour * 2); - await distribution.manageUsersInPrivatePool(poolId, [secondAddress, ownerAddress], [wei(1), wei(4)]); + let tx = await distribution.manageUsersInPrivatePool(poolId, [secondAddress, ownerAddress], [wei(1), wei(4)]); + await expect(tx).to.emit(distribution, 'UserStaked').withArgs(poolId, secondAddress, wei(1)); + await expect(tx).to.emit(distribution, 'UserStaked').withArgs(poolId, ownerAddress, wei(4)); expect(await depositToken.balanceOf(secondAddress)).to.eq(wei(1000)); expect(await rewardToken.balanceOf(secondAddress)).to.eq(wei(0)); @@ -361,7 +382,9 @@ describe('Distribution', () => { expect(userData.pendingRewards).to.eq(0); setNextTime(oneHour * 3); - await distribution.manageUsersInPrivatePool(poolId, [secondAddress, ownerAddress], [wei(10), wei(1)]); + tx = await distribution.manageUsersInPrivatePool(poolId, [secondAddress, ownerAddress], [wei(10), wei(1)]); + await expect(tx).to.emit(distribution, 'UserStaked').withArgs(poolId, secondAddress, wei(9)); + await expect(tx).to.emit(distribution, 'UserWithdrawn').withArgs(poolId, ownerAddress, wei(3)); expect(await depositToken.balanceOf(secondAddress)).to.eq(wei(1000)); expect(await rewardToken.balanceOf(secondAddress)).to.eq(wei(0)); @@ -665,7 +688,9 @@ describe('Distribution', () => { it('should stake correctly', async () => { // A stakes 1 token - await distribution.stake(poolId, wei(1)); + const tx = await distribution.stake(poolId, wei(1)); + await expect(tx).to.emit(distribution, 'UserStaked').withArgs(poolId, ownerAddress, wei(1)); + let userData = await distribution.usersData(ownerAddress, poolId); expect(userData.deposited).to.eq(wei(1)); expect(userData.rate).to.eq(0); @@ -735,7 +760,8 @@ describe('Distribution', () => { // Claim after 2 days await setNextTime(oneDay + oneDay * 2); - await distribution.claim(poolId, SECOND, { value: wei(0.5) }); + const tx = await distribution.claim(poolId, SECOND, { value: wei(0.5) }); + await expect(tx).to.emit(distribution, 'UserClaimed').withArgs(poolId, secondAddress, wei(198)); expect(await rewardToken.balanceOf(secondAddress)).to.eq(wei(198)); userData = await distribution.usersData(secondAddress, poolId); @@ -1066,15 +1092,14 @@ describe('Distribution', () => { await setNextTime(oneDay + oneDay); let tx = await distribution.claim(poolId, OWNER, { value: wei(0.5) }); - expect(tx).to.changeTokenBalance(rewardToken, OWNER, wei(1)); - + await expect(tx).to.changeTokenBalance(rewardToken, OWNER, wei(100)); let userData = await distribution.usersData(OWNER, poolId); expect(userData.pendingRewards).to.equal(wei(0)); await setNextTime(oneDay + oneDay * 2); tx = await distribution.claim(poolId, OWNER, { value: wei(0.5) }); - expect(tx).to.changeTokenBalance(rewardToken, OWNER, wei(0)); + await expect(tx).to.changeTokenBalance(rewardToken, OWNER, wei(98)); userData = await distribution.usersData(OWNER, poolId); expect(userData.pendingRewards).to.equal(wei(0)); }); @@ -1173,7 +1198,8 @@ describe('Distribution', () => { // Withdraw after 2 days await setNextTime(oneDay + oneDay * 2); - await distribution.connect(OWNER).withdraw(poolId, wei(999)); + const tx = await distribution.connect(OWNER).withdraw(poolId, wei(999)); + await expect(tx).to.emit(distribution, 'UserWithdrawn').withArgs(poolId, ownerAddress, wei(3)); await distribution.claim(poolId, OWNER, { value: wei(0.5) }); expect(await depositToken.balanceOf(ownerAddress)).to.eq(wei(1000)); @@ -1603,7 +1629,9 @@ describe('Distribution', () => { const overplus = await distribution.overplus(); expect(overplus).to.eq(wei(1)); + const bridgeMessageId = await distribution.bridgeOverplus.staticCall(1, 1, 1); const tx = await distribution.bridgeOverplus(1, 1, 1); + await expect(tx).to.emit(distribution, 'OverplusBridged').withArgs(wei(1), bridgeMessageId); await expect(tx).to.changeTokenBalance(depositToken, distribution, wei(-1)); expect(await wstETH.balanceOf(l2TokenReceiverAddress)).to.eq(wei(1)); }); diff --git a/test/fork/L2TokenReceiver.fork.test.ts b/test/fork/L2TokenReceiver.fork.test.ts index e265124..bbc2d98 100644 --- a/test/fork/L2TokenReceiver.fork.test.ts +++ b/test/fork/L2TokenReceiver.fork.test.ts @@ -30,7 +30,6 @@ describe('L2TokenReceiver Fork', () => { const wstethAddress = '0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0'; const usdcAddress = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'; - const wstethToUsdcRatio = wei(2399.01); const richAddress = '0x176F3DAb24a159341c0509bB36B833E7fdd0a132'; @@ -89,10 +88,11 @@ describe('L2TokenReceiver Fork', () => { }); it('should swap tokens', async () => { + const txResult = await l2TokenReceiver.swap.staticCall(amount, wei(0)); const tx = await l2TokenReceiver.swap(amount, wei(0)); - expect(tx).to.changeTokenBalance(outputToken, OWNER, amount); - expect(tx).to.changeTokenBalance(inputToken, OWNER, -amount * wstethToUsdcRatio); + await expect(tx).to.changeTokenBalance(outputToken, l2TokenReceiver, txResult); + await expect(tx).to.changeTokenBalance(inputToken, l2TokenReceiver, -amount); }); }); @@ -108,7 +108,7 @@ describe('L2TokenReceiver Fork', () => { }); it('should increase liquidity', async () => { - const tx = await l2TokenReceiver.increaseLiquidityCurrentRange.staticCall( + const txResult = await l2TokenReceiver.increaseLiquidityCurrentRange.staticCall( poolId, amountInputToken, amountOutputToken, @@ -116,10 +116,10 @@ describe('L2TokenReceiver Fork', () => { 0, ); - await l2TokenReceiver.increaseLiquidityCurrentRange(poolId, amountInputToken, amountOutputToken, 0, 0); + const tx = await l2TokenReceiver.increaseLiquidityCurrentRange(poolId, amountInputToken, amountOutputToken, 0, 0); - expect(tx).to.changeTokenBalance(outputToken, OWNER, -tx[1]); - expect(tx).to.changeTokenBalance(inputToken, OWNER, -tx[2]); + await expect(tx).to.changeTokenBalance(outputToken, l2TokenReceiver, -txResult[2]); + await expect(tx).to.changeTokenBalance(inputToken, l2TokenReceiver, -txResult[1]); }); it('should set the amount correctly besides the tokens order', async () => { const newParams: IL2TokenReceiver.SwapParamsStruct = { @@ -131,17 +131,17 @@ describe('L2TokenReceiver Fork', () => { await l2TokenReceiver.editParams(newParams); - const tx = await l2TokenReceiver.increaseLiquidityCurrentRange.staticCall( + const txResult = await l2TokenReceiver.increaseLiquidityCurrentRange.staticCall( poolId, amountInputToken, amountOutputToken, 0, 0, ); - await l2TokenReceiver.increaseLiquidityCurrentRange(poolId, amountInputToken, amountOutputToken, 0, 0); + const tx = await l2TokenReceiver.increaseLiquidityCurrentRange(poolId, amountInputToken, amountOutputToken, 0, 0); - expect(tx).to.changeTokenBalance(inputToken, OWNER, -tx[1]); - expect(tx).to.changeTokenBalance(outputToken, OWNER, -tx[2]); + await expect(tx).to.changeTokenBalance(inputToken, l2TokenReceiver, -txResult[1]); + await expect(tx).to.changeTokenBalance(outputToken, l2TokenReceiver, -txResult[2]); }); }); });