diff --git a/packages/router/contracts/adapters/PendlePtToAssetAdapter.sol b/packages/router/contracts/adapters/PendlePtToAssetAdapter.sol index b0ae1e84..40bcf26e 100644 --- a/packages/router/contracts/adapters/PendlePtToAssetAdapter.sol +++ b/packages/router/contracts/adapters/PendlePtToAssetAdapter.sol @@ -47,6 +47,7 @@ contract PendlePtToAssetAdapter is IMarginlyAdapter, Ownable2Step { uint256 private constant MAX_ITERATIONS = 10; mapping(address => mapping(address => PendleMarketData)) public getMarketData; + uint256 private callbackAmountIn; event NewPair(address indexed ptToken, address indexed asset, address pendleMarket, uint8 slippage); @@ -120,7 +121,10 @@ contract PendlePtToAssetAdapter is IMarginlyAdapter, Ownable2Step { } else { // this clause is realized when pt tokens is output // we need to mint SY from Asset and send to pendle - _pendleMintSy(marketData, msg.sender, uint256(-syToAccount), data); + (, uint256 amountIn) = _pendleMintSy(marketData, msg.sender, uint256(-syToAccount), data); + if (data.isExactOutput) { + callbackAmountIn = amountIn; + } } } @@ -203,10 +207,16 @@ contract PendlePtToAssetAdapter is IMarginlyAdapter, Ownable2Step { SafeERC20.safeTransfer(marketData.asset, recipient, amountOut); } else { // Sy to Pt -> in callback mint Sy from Asset and send to pendleMarket - (amountIn, ) = marketData.market.swapSyForExactPt(recipient, amountOut, abi.encode(swapCallbackData)); + marketData.market.swapSyForExactPt(recipient, amountOut, abi.encode(swapCallbackData)); + amountIn = _getAmountIn(); } } + function _getAmountIn() private returns (uint256 amountIn) { + amountIn = callbackAmountIn; + delete callbackAmountIn; + } + function _swapExactInputPostMaturity( PendleMarketData memory marketData, address recipient, @@ -310,19 +320,19 @@ contract PendlePtToAssetAdapter is IMarginlyAdapter, Ownable2Step { address recipient, uint256 syAmount, CallbackData memory data - ) private returns (uint256 syMinted) { + ) private returns (uint256 syMinted, uint256 actualAssetIn) { // Calculate amount of asset needed to mint syAmount - uint256 estimatedAssetIn = _syToAssetUpForDeposit(marketData, syAmount); + actualAssetIn = _syToAssetUpForDeposit(marketData, syAmount); if (data.isExactOutput) { //transfer estimatedAssetIn of Asset to adapter - IMarginlyRouter(data.router).adapterCallback(address(this), estimatedAssetIn, data.adapterCallbackData); + IMarginlyRouter(data.router).adapterCallback(address(this), actualAssetIn, data.adapterCallbackData); } - SafeERC20.forceApprove(marketData.asset, address(marketData.sy), estimatedAssetIn); + SafeERC20.forceApprove(marketData.asset, address(marketData.sy), actualAssetIn); syMinted = IStandardizedYield(marketData.sy).deposit( address(this), address(marketData.asset), - estimatedAssetIn, + actualAssetIn, syAmount ); diff --git a/packages/router/test/int/PendleCurveNgAdapterEBTC.eth.spec.ts b/packages/router/test/int/PendleCurveNgAdapterEBTC.eth.spec.ts index 72db766c..629445b0 100644 --- a/packages/router/test/int/PendleCurveNgAdapterEBTC.eth.spec.ts +++ b/packages/router/test/int/PendleCurveNgAdapterEBTC.eth.spec.ts @@ -7,7 +7,7 @@ import { PendleCurveNgAdapter, PendleCurveNgAdapter__factory, } from '../../typechain-types'; -import { constructSwap, Dex, showGasUsage, SWAP_ONE, resetFork } from '../shared/utils'; +import { constructSwap, Dex, showGasUsage, SWAP_ONE, resetFork, assertSwapEvent } from '../shared/utils'; import { EthAddress } from '@marginly/common'; import { formatUnits, parseUnits } from 'ethers/lib/utils'; import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; @@ -124,6 +124,18 @@ describe('PendleCurveAdapter PT-eBTC - WBTC', () => { const WBTCBalanceAfter = await WBTC.balanceOf(user.address); console.log(`WBTCBalanceAfter: ${formatUnits(WBTCBalanceAfter, await WBTC.decimals())} ${await WBTC.symbol()}`); expect(WBTCBalanceBefore.sub(WBTCBalanceAfter)).to.be.lessThanOrEqual(WBTCSwapAmount); + + await assertSwapEvent( + { + isExactInput: true, + tokenIn: WBTC.address, + tokenOut: ptToken.address, + amountIn: WBTCSwapAmount, + amountOut: ptBalanceAfter.sub(ptBalanceBefore), + }, + router, + tx + ); }); it('WBTC to PT-eBTC exact output', async () => { @@ -152,6 +164,18 @@ describe('PendleCurveAdapter PT-eBTC - WBTC', () => { console.log(`WBTCBalanceAfter: ${formatUnits(WBTCBalanceAfter, await WBTC.decimals())} ${await WBTC.symbol()}`); expect(WBTCBalanceBefore).to.be.greaterThan(WBTCBalanceAfter); + await assertSwapEvent( + { + isExactInput: false, + tokenIn: WBTC.address, + tokenOut: ptToken.address, + amountIn: WBTCBalanceBefore.sub(WBTCBalanceAfter), + amountOut: ptBalanceAfter.sub(ptBalanceBefore), + }, + router, + tx + ); + const ebtcOnAdapter = await ebtc.balanceOf(pendleCurveAdapter.address); console.log(`ebtc stays on adapter: ${formatUnits(ebtcOnAdapter, await ebtc.decimals())} ${await ebtc.symbol()}`); }); @@ -182,6 +206,18 @@ describe('PendleCurveAdapter PT-eBTC - WBTC', () => { console.log(`WBTCBalanceAfter: ${formatUnits(WBTCBalanceAfter, await WBTC.decimals())} ${await WBTC.symbol()}`); expect(WBTCBalanceBefore).to.be.greaterThan(WBTCBalanceAfter); + await assertSwapEvent( + { + isExactInput: false, + tokenIn: WBTC.address, + tokenOut: ptToken.address, + amountIn: WBTCBalanceBefore.sub(WBTCBalanceAfter), + amountOut: ptBalanceAfter.sub(ptBalanceBefore), + }, + router, + tx + ); + const ebtcOnAdapter = await ebtc.balanceOf(pendleCurveAdapter.address); console.log(`ebtc stays on adapter: ${formatUnits(ebtcOnAdapter, await ebtc.decimals())} ${await ebtc.symbol()}`); }); @@ -191,10 +227,8 @@ describe('PendleCurveAdapter PT-eBTC - WBTC', () => { console.log( `ptBalanceBefore: ${formatUnits(ptBalanceBefore, await ptToken.decimals())} ${await ptToken.symbol()}` ); - const sUSDeBalanceBefore = await WBTC.balanceOf(user.address); - console.log( - `WBTCBalanceBefore: ${formatUnits(sUSDeBalanceBefore, await WBTC.decimals())} ${await WBTC.symbol()}` - ); + const WBTCBalanceBefore = await WBTC.balanceOf(user.address); + console.log(`WBTCBalanceBefore: ${formatUnits(WBTCBalanceBefore, await WBTC.decimals())} ${await WBTC.symbol()}`); const swapCalldata = constructSwap([Dex.PendleCurve], [SWAP_ONE]); const ptIn = parseUnits('0.1', 8); await ptToken.connect(user).approve(router.address, ptIn); @@ -204,9 +238,21 @@ describe('PendleCurveAdapter PT-eBTC - WBTC', () => { const ptBalanceAfter = await ptToken.balanceOf(user.address); console.log(`ptBalanceAfter: ${formatUnits(ptBalanceAfter, await ptToken.decimals())} ${await ptToken.symbol()}`); expect(ptBalanceBefore.sub(ptBalanceAfter)).to.be.eq(ptIn); - const sUsdeBalanceAfter = await WBTC.balanceOf(user.address); - console.log(`WBTCBalanceAfter: ${formatUnits(sUsdeBalanceAfter, await WBTC.decimals())} ${await WBTC.symbol()}`); - expect(sUsdeBalanceAfter).to.be.greaterThan(sUSDeBalanceBefore); + const WBTCBalanceAfter = await WBTC.balanceOf(user.address); + console.log(`WBTCBalanceAfter: ${formatUnits(WBTCBalanceAfter, await WBTC.decimals())} ${await WBTC.symbol()}`); + expect(WBTCBalanceAfter).to.be.greaterThan(WBTCBalanceBefore); + + await assertSwapEvent( + { + isExactInput: true, + tokenIn: ptToken.address, + tokenOut: WBTC.address, + amountIn: ptBalanceBefore.sub(ptBalanceAfter), + amountOut: WBTCBalanceAfter.sub(WBTCBalanceBefore), + }, + router, + tx + ); }); it('PT-eBTC to WBTC exact output', async () => { @@ -236,6 +282,18 @@ describe('PendleCurveAdapter PT-eBTC - WBTC', () => { console.log( `WBTCBalanceOnAdapter: ${formatUnits(WBTCBalanceOnAdapter, await WBTC.decimals())} ${await WBTC.symbol()}` ); + + await assertSwapEvent( + { + isExactInput: false, + tokenIn: ptToken.address, + tokenOut: WBTC.address, + amountIn: ptBalanceBefore.sub(ptBalanceAfter), + amountOut: WBTCBalanceAfter.sub(WBTCBalanceBefore), + }, + router, + tx + ); }); }); @@ -344,6 +402,18 @@ describe('PendleCurveAdapter PT-eBTC - WBTC', () => { const WBTCBalanceAfter = await WBTC.balanceOf(user.address); console.log(`WBTCBalanceAfter: ${formatUnits(WBTCBalanceAfter, await WBTC.decimals())} ${await WBTC.symbol()}`); expect(WBTCBalanceAfter).to.be.greaterThan(WBTCBalanceBefore); + + await assertSwapEvent( + { + isExactInput: true, + tokenIn: ptToken.address, + tokenOut: WBTC.address, + amountIn: ptBalanceBefore.sub(ptBalanceAfter), + amountOut: WBTCBalanceAfter.sub(WBTCBalanceBefore), + }, + router, + tx + ); }); it('PT-eBTC to WBTC exact output', async () => { @@ -351,9 +421,9 @@ describe('PendleCurveAdapter PT-eBTC - WBTC', () => { console.log( `ptBalanceBefore: ${formatUnits(ptBalanceBefore, await ptToken.decimals())} ${await ptToken.symbol()}` ); - const sUsdeBalanceBefore = await WBTC.balanceOf(user.address); + const WBTCBalanceBefore = await WBTC.balanceOf(user.address); console.log( - `sUsdeBalanceBefore: ${formatUnits(sUsdeBalanceBefore, await WBTC.decimals())} ${await WBTC.symbol()}` + `WBTCBalanceBefore: ${formatUnits(WBTCBalanceBefore, await WBTC.decimals())} ${await WBTC.symbol()}` ); const swapCalldata = constructSwap([Dex.PendleCurve], [SWAP_ONE]); @@ -370,7 +440,19 @@ describe('PendleCurveAdapter PT-eBTC - WBTC', () => { expect(ptBalanceBefore).to.be.greaterThan(ptBalanceAfter); const WBTCBalanceAfter = await WBTC.balanceOf(user.address); console.log(`sUsdeBalanceAfter: ${formatUnits(WBTCBalanceAfter, await WBTC.decimals())} ${await WBTC.symbol()}`); - expect(WBTCBalanceAfter.sub(sUsdeBalanceBefore)).to.be.eq(WBTCOut); + expect(WBTCBalanceAfter.sub(WBTCBalanceBefore)).to.be.eq(WBTCOut); + + await assertSwapEvent( + { + isExactInput: false, + tokenIn: ptToken.address, + tokenOut: WBTC.address, + amountIn: ptBalanceBefore.sub(ptBalanceAfter), + amountOut: WBTCBalanceAfter.sub(WBTCBalanceBefore), + }, + router, + tx + ); }); }); }); diff --git a/packages/router/test/int/PendleCurveNgAdapterEthena.eth.spec.ts b/packages/router/test/int/PendleCurveNgAdapterEthena.eth.spec.ts index 0a3af2b9..67af2fd7 100644 --- a/packages/router/test/int/PendleCurveNgAdapterEthena.eth.spec.ts +++ b/packages/router/test/int/PendleCurveNgAdapterEthena.eth.spec.ts @@ -7,7 +7,7 @@ import { PendleCurveNgAdapter, PendleCurveNgAdapter__factory, } from '../../typechain-types'; -import { constructSwap, Dex, resetFork, showBalance, showGasUsage, SWAP_ONE } from '../shared/utils'; +import { assertSwapEvent, constructSwap, Dex, resetFork, showBalance, showGasUsage, SWAP_ONE } from '../shared/utils'; import { EthAddress } from '@marginly/common'; import { formatUnits, parseUnits } from 'ethers/lib/utils'; import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; @@ -139,6 +139,18 @@ describe('PendleCurveAdapter PT-usde - usdc', () => { expect(usdcBalanceBefore).to.be.greaterThan(usdcBalanceAfter); await showBalance(usde, pendleCurveAdapter.address, 'usde stays on adapter: '); + + await assertSwapEvent( + { + isExactInput: false, + tokenIn: usdc.address, + tokenOut: ptToken.address, + amountIn: usdcBalanceBefore.sub(usdcBalanceAfter), + amountOut: ptBalanceAfter.sub(ptBalanceBefore), + }, + router, + tx + ); }); it('USDC to pt-USDe exact output, small amount', async () => { @@ -162,6 +174,18 @@ describe('PendleCurveAdapter PT-usde - usdc', () => { expect(usdcBalanceBefore).to.be.greaterThan(usdcBalanceAfter); await showBalance(usde, pendleCurveAdapter.address, 'usde stays on adapter: '); + + await assertSwapEvent( + { + isExactInput: false, + tokenIn: usdc.address, + tokenOut: ptToken.address, + amountIn: usdcBalanceBefore.sub(usdcBalanceAfter), + amountOut: ptBalanceAfter.sub(ptBalanceBefore), + }, + router, + tx + ); }); it('pt-USDe to USDC exact input', async () => { @@ -179,6 +203,18 @@ describe('PendleCurveAdapter PT-usde - usdc', () => { const usdcBalanceAfter = await showBalance(usdc, user.address, 'usdc balance After:'); expect(usdcBalanceAfter).to.be.greaterThan(usdcBalanceBefore); + + await assertSwapEvent( + { + isExactInput: true, + tokenIn: ptToken.address, + tokenOut: usdc.address, + amountIn: ptBalanceBefore.sub(ptBalanceAfter), + amountOut: usdcBalanceAfter.sub(usdcBalanceBefore), + }, + router, + tx + ); }); it('pt-USDe to USDC exact output', async () => { @@ -201,6 +237,18 @@ describe('PendleCurveAdapter PT-usde - usdc', () => { expect(usdcBalanceAfter.sub(usdcBalanceBefore)).to.be.eq(usdcOut); await showBalance(usdc, pendleCurveAdapter.address, 'USDC stays on adapter: '); + + await assertSwapEvent( + { + isExactInput: false, + tokenIn: ptToken.address, + tokenOut: usdc.address, + amountIn: ptBalanceBefore.sub(ptBalanceAfter), + amountOut: usdcBalanceAfter.sub(usdcBalanceBefore), + }, + router, + tx + ); }); }); @@ -292,6 +340,18 @@ describe('PendleCurveAdapter PT-usde - usdc', () => { const usdcBalanceAfter = await showBalance(usdc, user.address, 'usdc balance After:'); expect(usdcBalanceAfter).to.be.greaterThan(usdcBalanceBefore); + + await assertSwapEvent( + { + isExactInput: true, + tokenIn: ptToken.address, + tokenOut: usdc.address, + amountIn: ptBalanceBefore.sub(ptBalanceAfter), + amountOut: usdcBalanceAfter.sub(usdcBalanceBefore), + }, + router, + tx + ); }); it('pt-USDe to USDC exact output', async () => { @@ -312,6 +372,18 @@ describe('PendleCurveAdapter PT-usde - usdc', () => { const usdcBalanceAfter = await showBalance(usdc, user.address, 'usdc balance After:'); expect(usdcBalanceAfter.sub(usdcBalanceBefore)).to.be.eq(usdcOut); + + await assertSwapEvent( + { + isExactInput: false, + tokenIn: ptToken.address, + tokenOut: usdc.address, + amountIn: ptBalanceBefore.sub(ptBalanceAfter), + amountOut: usdcBalanceAfter.sub(usdcBalanceBefore), + }, + router, + tx + ); }); }); }); diff --git a/packages/router/test/int/PendleCurveNgAdapterWEETH.eth.spec.ts b/packages/router/test/int/PendleCurveNgAdapterWEETH.eth.spec.ts index 7a102873..ff0a8daa 100644 --- a/packages/router/test/int/PendleCurveNgAdapterWEETH.eth.spec.ts +++ b/packages/router/test/int/PendleCurveNgAdapterWEETH.eth.spec.ts @@ -7,7 +7,7 @@ import { PendleCurveNgAdapter, PendleCurveNgAdapter__factory, } from '../../typechain-types'; -import { constructSwap, Dex, resetFork, showGasUsage, SWAP_ONE } from '../shared/utils'; +import { assertSwapEvent, constructSwap, Dex, resetFork, showGasUsage, SWAP_ONE } from '../shared/utils'; import { EthAddress } from '@marginly/common'; import { formatUnits, parseUnits } from 'ethers/lib/utils'; import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; @@ -123,6 +123,18 @@ describe('PendleCurveAdapter PT-eETH - WETH', () => { const WETHBalanceAfter = await WETH.balanceOf(user.address); console.log(`WETHBalanceAfter: ${formatUnits(WETHBalanceAfter, await WETH.decimals())} ${await WETH.symbol()}`); expect(WETHBalanceBefore.sub(WETHBalanceAfter)).to.be.lessThanOrEqual(WETHSwapAmount); + + await assertSwapEvent( + { + isExactInput: true, + tokenIn: WETH.address, + tokenOut: ptToken.address, + amountIn: WETHBalanceBefore.sub(WETHBalanceAfter), + amountOut: ptBalanceAfter.sub(ptBalanceBefore), + }, + router, + tx + ); }); it('WETH to PT-eETH exact output', async () => { @@ -153,6 +165,18 @@ describe('PendleCurveAdapter PT-eETH - WETH', () => { const ebtcOnAdapter = await ebtc.balanceOf(pendleCurveAdapter.address); console.log(`ebtc stays on adapter: ${formatUnits(ebtcOnAdapter, await ebtc.decimals())} ${await ebtc.symbol()}`); + + await assertSwapEvent( + { + isExactInput: false, + tokenIn: WETH.address, + tokenOut: ptToken.address, + amountIn: WETHBalanceBefore.sub(WETHBalanceAfter), + amountOut: ptBalanceAfter.sub(ptBalanceBefore), + }, + router, + tx + ); }); it('WETH to PT-eETH exact output, small amount', async () => { @@ -183,6 +207,18 @@ describe('PendleCurveAdapter PT-eETH - WETH', () => { const ebtcOnAdapter = await ebtc.balanceOf(pendleCurveAdapter.address); console.log(`ebtc stays on adapter: ${formatUnits(ebtcOnAdapter, await ebtc.decimals())} ${await ebtc.symbol()}`); + + await assertSwapEvent( + { + isExactInput: false, + tokenIn: WETH.address, + tokenOut: ptToken.address, + amountIn: WETHBalanceBefore.sub(WETHBalanceAfter), + amountOut: ptBalanceAfter.sub(ptBalanceBefore), + }, + router, + tx + ); }); it('PT-eETH to WETH exact input', async () => { @@ -190,10 +226,8 @@ describe('PendleCurveAdapter PT-eETH - WETH', () => { console.log( `ptBalanceBefore: ${formatUnits(ptBalanceBefore, await ptToken.decimals())} ${await ptToken.symbol()}` ); - const sUSDeBalanceBefore = await WETH.balanceOf(user.address); - console.log( - `WETHBalanceBefore: ${formatUnits(sUSDeBalanceBefore, await WETH.decimals())} ${await WETH.symbol()}` - ); + const WETHBalanceBefore = await WETH.balanceOf(user.address); + console.log(`WETHBalanceBefore: ${formatUnits(WETHBalanceBefore, await WETH.decimals())} ${await WETH.symbol()}`); const swapCalldata = constructSwap([Dex.PendleCurve], [SWAP_ONE]); const ptIn = parseUnits('0.1', 18); await ptToken.connect(user).approve(router.address, ptIn); @@ -203,9 +237,21 @@ describe('PendleCurveAdapter PT-eETH - WETH', () => { const ptBalanceAfter = await ptToken.balanceOf(user.address); console.log(`ptBalanceAfter: ${formatUnits(ptBalanceAfter, await ptToken.decimals())} ${await ptToken.symbol()}`); expect(ptBalanceBefore.sub(ptBalanceAfter)).to.be.eq(ptIn); - const sUsdeBalanceAfter = await WETH.balanceOf(user.address); - console.log(`WETHBalanceAfter: ${formatUnits(sUsdeBalanceAfter, await WETH.decimals())} ${await WETH.symbol()}`); - expect(sUsdeBalanceAfter).to.be.greaterThan(sUSDeBalanceBefore); + const WETHBalanceAfter = await WETH.balanceOf(user.address); + console.log(`WETHBalanceAfter: ${formatUnits(WETHBalanceAfter, await WETH.decimals())} ${await WETH.symbol()}`); + expect(WETHBalanceAfter).to.be.greaterThan(WETHBalanceBefore); + + await assertSwapEvent( + { + isExactInput: true, + tokenIn: ptToken.address, + tokenOut: WETH.address, + amountIn: ptBalanceBefore.sub(ptBalanceAfter), + amountOut: WETHBalanceAfter.sub(WETHBalanceBefore), + }, + router, + tx + ); }); it('PT-eETH to WETH exact output', async () => { @@ -235,6 +281,18 @@ describe('PendleCurveAdapter PT-eETH - WETH', () => { console.log( `WETHBalanceOnAdapter: ${formatUnits(WETHBalanceOnAdapter, await WETH.decimals())} ${await WETH.symbol()}` ); + + await assertSwapEvent( + { + isExactInput: false, + tokenIn: ptToken.address, + tokenOut: WETH.address, + amountIn: ptBalanceBefore.sub(ptBalanceAfter), + amountOut: WETHBalanceAfter.sub(WETHBalanceBefore), + }, + router, + tx + ); }); }); @@ -268,21 +326,19 @@ describe('PendleCurveAdapter PT-eETH - WETH', () => { console.log( `ptBalanceBefore: ${formatUnits(ptBalanceBefore, await ptToken.decimals())} ${await ptToken.symbol()}` ); - const sUsdeBalanceBefore = await WETH.balanceOf(user.address); - console.log( - `WETHBalanceBefore: ${formatUnits(sUsdeBalanceBefore, await WETH.decimals())} ${await WETH.symbol()}` - ); + const WETHBalanceBefore = await WETH.balanceOf(user.address); + console.log(`WETHBalanceBefore: ${formatUnits(WETHBalanceBefore, await WETH.decimals())} ${await WETH.symbol()}`); const swapCalldata = constructSwap([Dex.PendleCurve], [SWAP_ONE]); - await WETH.connect(user).approve(router.address, sUsdeBalanceBefore); + await WETH.connect(user).approve(router.address, WETHBalanceBefore); const tx = router .connect(user) .swapExactInput( swapCalldata, WETH.address, ptToken.address, - sUsdeBalanceBefore, - sUsdeBalanceBefore.mul(9).div(10) + WETHBalanceBefore, + WETHBalanceBefore.mul(9).div(10) ); await expect(tx).to.be.revertedWithCustomError(pendleCurveAdapter, 'NotSupported'); @@ -291,9 +347,9 @@ describe('PendleCurveAdapter PT-eETH - WETH', () => { const ptBalanceAfter = await ptToken.balanceOf(user.address); console.log(`ptBalanceAfter: ${formatUnits(ptBalanceAfter, await ptToken.decimals())} ${await ptToken.symbol()}`); expect(ptBalanceAfter).to.be.eq(ptBalanceBefore); - const sUsdeBalanceAfter = await WETH.balanceOf(user.address); - console.log(`WETHBalanceAfter: ${formatUnits(sUsdeBalanceAfter, await WETH.decimals())} ${await WETH.symbol()}`); - expect(sUsdeBalanceAfter).to.be.eq(sUsdeBalanceBefore); + const WETHBalanceAfter = await WETH.balanceOf(user.address); + console.log(`WETHBalanceAfter: ${formatUnits(WETHBalanceAfter, await WETH.decimals())} ${await WETH.symbol()}`); + expect(WETHBalanceAfter).to.be.eq(WETHBalanceBefore); }); it('WETH to PT-eETH exact output, forbidden', async () => { @@ -346,6 +402,18 @@ describe('PendleCurveAdapter PT-eETH - WETH', () => { const WETHBalanceAfter = await WETH.balanceOf(user.address); console.log(`WETHBalanceAfter: ${formatUnits(WETHBalanceAfter, await WETH.decimals())} ${await WETH.symbol()}`); expect(WETHBalanceAfter).to.be.greaterThan(WETHBalanceBefore); + + await assertSwapEvent( + { + isExactInput: true, + tokenIn: ptToken.address, + tokenOut: WETH.address, + amountIn: ptBalanceBefore.sub(ptBalanceAfter), + amountOut: WETHBalanceAfter.sub(WETHBalanceBefore), + }, + router, + tx + ); }); it('PT-eETH to WETH exact output', async () => { @@ -353,10 +421,8 @@ describe('PendleCurveAdapter PT-eETH - WETH', () => { console.log( `ptBalanceBefore: ${formatUnits(ptBalanceBefore, await ptToken.decimals())} ${await ptToken.symbol()}` ); - const sUsdeBalanceBefore = await WETH.balanceOf(user.address); - console.log( - `sUsdeBalanceBefore: ${formatUnits(sUsdeBalanceBefore, await WETH.decimals())} ${await WETH.symbol()}` - ); + const WETHBalanceBefore = await WETH.balanceOf(user.address); + console.log(`WETHBalanceBefore: ${formatUnits(WETHBalanceBefore, await WETH.decimals())} ${await WETH.symbol()}`); const swapCalldata = constructSwap([Dex.PendleCurve], [SWAP_ONE]); const WETHOut = parseUnits('0.9', await WETH.decimals()); @@ -372,7 +438,19 @@ describe('PendleCurveAdapter PT-eETH - WETH', () => { expect(ptBalanceBefore).to.be.greaterThan(ptBalanceAfter); const WETHBalanceAfter = await WETH.balanceOf(user.address); console.log(`sUsdeBalanceAfter: ${formatUnits(WETHBalanceAfter, await WETH.decimals())} ${await WETH.symbol()}`); - expect(WETHBalanceAfter.sub(sUsdeBalanceBefore)).to.be.eq(WETHOut); + expect(WETHBalanceAfter.sub(WETHBalanceBefore)).to.be.eq(WETHOut); + + await assertSwapEvent( + { + isExactInput: false, + tokenIn: ptToken.address, + tokenOut: WETH.address, + amountIn: ptBalanceBefore.sub(ptBalanceAfter), + amountOut: WETHBalanceAfter.sub(WETHBalanceBefore), + }, + router, + tx + ); }); }); }); diff --git a/packages/router/test/int/PendleCurveRouterNgEthena.eth.spec.ts b/packages/router/test/int/PendleCurveRouterNgEthena.eth.spec.ts index 17d25cf2..1679b9f6 100644 --- a/packages/router/test/int/PendleCurveRouterNgEthena.eth.spec.ts +++ b/packages/router/test/int/PendleCurveRouterNgEthena.eth.spec.ts @@ -7,7 +7,7 @@ import { PendleCurveRouterNgAdapter, PendleCurveRouterNgAdapter__factory, } from '../../typechain-types'; -import { constructSwap, Dex, resetFork, showGasUsage, SWAP_ONE } from '../shared/utils'; +import { constructSwap, Dex, resetFork, showGasUsage, SWAP_ONE, assertSwapEvent } from '../shared/utils'; import { EthAddress } from '@marginly/common'; import { formatUnits, parseUnits } from 'ethers/lib/utils'; import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; @@ -150,6 +150,18 @@ describe('PendleCurveRouter PT-usde - usdc', () => { const usdcBalanceAfter = await usdc.balanceOf(user.address); console.log(`usdcBalanceAfter: ${formatUnits(usdcBalanceAfter, await usdc.decimals())} ${await usdc.symbol()}`); expect(usdcBalanceBefore.sub(usdcBalanceAfter)).to.be.lessThanOrEqual(usdcSwapAmount); + + await assertSwapEvent( + { + isExactInput: true, + tokenIn: usdc.address, + tokenOut: ptToken.address, + amountIn: usdcBalanceBefore.sub(usdcBalanceAfter), + amountOut: ptBalanceAfter.sub(ptBalanceBefore), + }, + router, + tx + ); }); it('USDC to pt-USDe exact output', async () => { @@ -182,6 +194,18 @@ describe('PendleCurveRouter PT-usde - usdc', () => { console.log( `usde stays on adapter: ${formatUnits(usd0PlusPlusOnAdapter, await usde.decimals())} ${await usde.symbol()}` ); + + await assertSwapEvent( + { + isExactInput: false, + tokenIn: usdc.address, + tokenOut: ptToken.address, + amountIn: usdcBalanceBefore.sub(usdcBalanceAfter), + amountOut: ptBalanceAfter.sub(ptBalanceBefore), + }, + router, + tx + ); }); it('pt-USDe to USDC exact input', async () => { @@ -189,10 +213,8 @@ describe('PendleCurveRouter PT-usde - usdc', () => { console.log( `ptBalanceBefore: ${formatUnits(ptBalanceBefore, await ptToken.decimals())} ${await ptToken.symbol()}` ); - const sUSDeBalanceBefore = await usdc.balanceOf(user.address); - console.log( - `usdcBalanceBefore: ${formatUnits(sUSDeBalanceBefore, await usdc.decimals())} ${await usdc.symbol()}` - ); + const usdcBalanceBefore = await usdc.balanceOf(user.address); + console.log(`usdcBalanceBefore: ${formatUnits(usdcBalanceBefore, await usdc.decimals())} ${await usdc.symbol()}`); const swapCalldata = constructSwap([Dex.PendleCurveRouter], [SWAP_ONE]); const ptIn = ptBalanceBefore; await ptToken.connect(user).approve(router.address, ptIn); @@ -202,9 +224,21 @@ describe('PendleCurveRouter PT-usde - usdc', () => { const ptBalanceAfter = await ptToken.balanceOf(user.address); console.log(`ptBalanceAfter: ${formatUnits(ptBalanceAfter, await ptToken.decimals())} ${await ptToken.symbol()}`); expect(ptBalanceBefore.sub(ptBalanceAfter)).to.be.eq(ptIn); - const sUsdeBalanceAfter = await usdc.balanceOf(user.address); - console.log(`usdcBalanceAfter: ${formatUnits(sUsdeBalanceAfter, await usdc.decimals())} ${await usdc.symbol()}`); - expect(sUsdeBalanceAfter).to.be.greaterThan(sUSDeBalanceBefore); + const usdcBalanceAfter = await usdc.balanceOf(user.address); + console.log(`usdcBalanceAfter: ${formatUnits(usdcBalanceAfter, await usdc.decimals())} ${await usdc.symbol()}`); + expect(usdcBalanceAfter).to.be.greaterThan(usdcBalanceBefore); + + await assertSwapEvent( + { + isExactInput: true, + tokenIn: ptToken.address, + tokenOut: usdc.address, + amountIn: ptBalanceBefore.sub(ptBalanceAfter), + amountOut: usdcBalanceAfter.sub(usdcBalanceBefore), + }, + router, + tx + ); }); it('pt-USDe to USDC exact output', async () => { @@ -234,6 +268,18 @@ describe('PendleCurveRouter PT-usde - usdc', () => { console.log( `usdcBalanceOnAdapter: ${formatUnits(usdcBalanceOnAdapter, await usdc.decimals())} ${await usdc.symbol()}` ); + + await assertSwapEvent( + { + isExactInput: false, + tokenIn: ptToken.address, + tokenOut: usdc.address, + amountIn: ptBalanceBefore.sub(ptBalanceAfter), + amountOut: usdcBalanceAfter.sub(usdcBalanceBefore), + }, + router, + tx + ); }); }); @@ -342,6 +388,18 @@ describe('PendleCurveRouter PT-usde - usdc', () => { const usdcBalanceAfter = await usdc.balanceOf(user.address); console.log(`usdcBalanceAfter: ${formatUnits(usdcBalanceAfter, await usdc.decimals())} ${await usdc.symbol()}`); expect(usdcBalanceAfter).to.be.greaterThan(usdcBalanceBefore); + + await assertSwapEvent( + { + isExactInput: true, + tokenIn: ptToken.address, + tokenOut: usdc.address, + amountIn: ptBalanceBefore.sub(ptBalanceAfter), + amountOut: usdcBalanceAfter.sub(usdcBalanceBefore), + }, + router, + tx + ); }); it('pt-USDe to USDC exact output', async () => { @@ -349,10 +407,8 @@ describe('PendleCurveRouter PT-usde - usdc', () => { console.log( `ptBalanceBefore: ${formatUnits(ptBalanceBefore, await ptToken.decimals())} ${await ptToken.symbol()}` ); - const sUsdeBalanceBefore = await usdc.balanceOf(user.address); - console.log( - `sUsdeBalanceBefore: ${formatUnits(sUsdeBalanceBefore, await usdc.decimals())} ${await usdc.symbol()}` - ); + const usdcBalanceBefore = await usdc.balanceOf(user.address); + console.log(`usdcBalanceBefore: ${formatUnits(usdcBalanceBefore, await usdc.decimals())} ${await usdc.symbol()}`); const swapCalldata = constructSwap([Dex.PendleCurveRouter], [SWAP_ONE]); const usdcOut = parseUnits('900', 6); @@ -367,8 +423,20 @@ describe('PendleCurveRouter PT-usde - usdc', () => { console.log(`ptBalanceAfter: ${formatUnits(ptBalanceAfter, await ptToken.decimals())} ${await ptToken.symbol()}`); expect(ptBalanceBefore).to.be.greaterThan(ptBalanceAfter); const usdcBalanceAfter = await usdc.balanceOf(user.address); - console.log(`sUsdeBalanceAfter: ${formatUnits(usdcBalanceAfter, await usdc.decimals())} ${await usdc.symbol()}`); - expect(usdcBalanceAfter.sub(sUsdeBalanceBefore)).to.be.eq(usdcOut); + console.log(`usdcBalanceAfter: ${formatUnits(usdcBalanceAfter, await usdc.decimals())} ${await usdc.symbol()}`); + expect(usdcBalanceAfter.sub(usdcBalanceBefore)).to.be.eq(usdcOut); + + await assertSwapEvent( + { + isExactInput: false, + tokenIn: ptToken.address, + tokenOut: usdc.address, + amountIn: ptBalanceBefore.sub(ptBalanceAfter), + amountOut: usdcBalanceAfter.sub(usdcBalanceBefore), + }, + router, + tx + ); }); }); }); diff --git a/packages/router/test/int/PendleCurveRouterNgUSD0.eth.spec.ts b/packages/router/test/int/PendleCurveRouterNgUSD0.eth.spec.ts index 2531a5ee..ef92e5a1 100644 --- a/packages/router/test/int/PendleCurveRouterNgUSD0.eth.spec.ts +++ b/packages/router/test/int/PendleCurveRouterNgUSD0.eth.spec.ts @@ -7,7 +7,7 @@ import { PendleCurveRouterNgAdapter, PendleCurveRouterNgAdapter__factory, } from '../../typechain-types'; -import { constructSwap, Dex, resetFork, showGasUsage, SWAP_ONE } from '../shared/utils'; +import { constructSwap, Dex, resetFork, showGasUsage, SWAP_ONE, assertSwapEvent } from '../shared/utils'; import { EthAddress } from '@marginly/common'; import { formatUnits, parseUnits } from 'ethers/lib/utils'; import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; @@ -185,6 +185,18 @@ describe('Pendle PT-usd0++ - usdc', () => { await usd0PlusPlusToken.decimals() )} ${await usd0PlusPlusToken.symbol()}` ); + + await assertSwapEvent( + { + isExactInput: false, + tokenIn: usdc.address, + tokenOut: ptToken.address, + amountIn: usdcBalanceBefore.sub(usdcBalanceAfter), + amountOut: ptBalanceAfter.sub(ptBalanceBefore), + }, + router, + tx + ); }); it('USDC to pt-USD0++ exact output, small amount', async () => { @@ -220,6 +232,18 @@ describe('Pendle PT-usd0++ - usdc', () => { await usd0PlusPlusToken.decimals() )} ${await usd0PlusPlusToken.symbol()}` ); + + await assertSwapEvent( + { + isExactInput: false, + tokenIn: usdc.address, + tokenOut: ptToken.address, + amountIn: usdcBalanceBefore.sub(usdcBalanceAfter), + amountOut: ptBalanceAfter.sub(ptBalanceBefore), + }, + router, + tx + ); }); it('pt-USD0++ to USDC exact input', async () => { @@ -227,10 +251,8 @@ describe('Pendle PT-usd0++ - usdc', () => { console.log( `ptBalanceBefore: ${formatUnits(ptBalanceBefore, await ptToken.decimals())} ${await ptToken.symbol()}` ); - const sUSDeBalanceBefore = await usdc.balanceOf(user.address); - console.log( - `usdcBalanceBefore: ${formatUnits(sUSDeBalanceBefore, await usdc.decimals())} ${await usdc.symbol()}` - ); + const usdcBalanceBefore = await usdc.balanceOf(user.address); + console.log(`usdcBalanceBefore: ${formatUnits(usdcBalanceBefore, await usdc.decimals())} ${await usdc.symbol()}`); const swapCalldata = constructSwap([Dex.PendleCurveRouter], [SWAP_ONE]); const ptIn = ptBalanceBefore; await ptToken.connect(user).approve(router.address, ptIn); @@ -240,9 +262,21 @@ describe('Pendle PT-usd0++ - usdc', () => { const ptBalanceAfter = await ptToken.balanceOf(user.address); console.log(`ptBalanceAfter: ${formatUnits(ptBalanceAfter, await ptToken.decimals())} ${await ptToken.symbol()}`); expect(ptBalanceBefore.sub(ptBalanceAfter)).to.be.eq(ptIn); - const sUsdeBalanceAfter = await usdc.balanceOf(user.address); - console.log(`usdcBalanceAfter: ${formatUnits(sUsdeBalanceAfter, await usdc.decimals())} ${await usdc.symbol()}`); - expect(sUsdeBalanceAfter).to.be.greaterThan(sUSDeBalanceBefore); + const usdcBalanceAfter = await usdc.balanceOf(user.address); + console.log(`usdcBalanceAfter: ${formatUnits(usdcBalanceAfter, await usdc.decimals())} ${await usdc.symbol()}`); + expect(usdcBalanceAfter).to.be.greaterThan(usdcBalanceBefore); + + await assertSwapEvent( + { + isExactInput: true, + tokenIn: ptToken.address, + tokenOut: usdc.address, + amountIn: ptBalanceBefore.sub(ptBalanceAfter), + amountOut: usdcBalanceAfter.sub(usdcBalanceBefore), + }, + router, + tx + ); }); it('pt-USD0++ to USDC exact output', async () => { @@ -272,6 +306,18 @@ describe('Pendle PT-usd0++ - usdc', () => { console.log( `usdcBalanceOnAdapter: ${formatUnits(usdcBalanceOnAdapter, await usdc.decimals())} ${await usdc.symbol()}` ); + + await assertSwapEvent( + { + isExactInput: false, + tokenIn: ptToken.address, + tokenOut: usdc.address, + amountIn: ptBalanceBefore.sub(ptBalanceAfter), + amountOut: usdcBalanceAfter.sub(usdcBalanceBefore), + }, + router, + tx + ); }); }); @@ -380,6 +426,18 @@ describe('Pendle PT-usd0++ - usdc', () => { const usdcBalanceAfter = await usdc.balanceOf(user.address); console.log(`usdcBalanceAfter: ${formatUnits(usdcBalanceAfter, await usdc.decimals())} ${await usdc.symbol()}`); expect(usdcBalanceAfter).to.be.greaterThan(usdcBalanceBefore); + + await assertSwapEvent( + { + isExactInput: true, + tokenIn: ptToken.address, + tokenOut: usdc.address, + amountIn: ptBalanceBefore.sub(ptBalanceAfter), + amountOut: usdcBalanceAfter.sub(usdcBalanceBefore), + }, + router, + tx + ); }); it('pt-usd0++ to USDC exact output', async () => { @@ -387,10 +445,8 @@ describe('Pendle PT-usd0++ - usdc', () => { console.log( `ptBalanceBefore: ${formatUnits(ptBalanceBefore, await ptToken.decimals())} ${await ptToken.symbol()}` ); - const sUsdeBalanceBefore = await usdc.balanceOf(user.address); - console.log( - `sUsdeBalanceBefore: ${formatUnits(sUsdeBalanceBefore, await usdc.decimals())} ${await usdc.symbol()}` - ); + const usdcBalanceBefore = await usdc.balanceOf(user.address); + console.log(`usdcBalanceBefore: ${formatUnits(usdcBalanceBefore, await usdc.decimals())} ${await usdc.symbol()}`); const swapCalldata = constructSwap([Dex.PendleCurveRouter], [SWAP_ONE]); const usdcOut = parseUnits('900', 6); @@ -406,7 +462,19 @@ describe('Pendle PT-usd0++ - usdc', () => { expect(ptBalanceBefore).to.be.greaterThan(ptBalanceAfter); const usdcBalanceAfter = await usdc.balanceOf(user.address); console.log(`sUsdeBalanceAfter: ${formatUnits(usdcBalanceAfter, await usdc.decimals())} ${await usdc.symbol()}`); - expect(usdcBalanceAfter.sub(sUsdeBalanceBefore)).to.be.eq(usdcOut); + expect(usdcBalanceAfter.sub(usdcBalanceBefore)).to.be.eq(usdcOut); + + await assertSwapEvent( + { + isExactInput: false, + tokenIn: ptToken.address, + tokenOut: usdc.address, + amountIn: ptBalanceBefore.sub(ptBalanceAfter), + amountOut: usdcBalanceAfter.sub(usdcBalanceBefore), + }, + router, + tx + ); }); }); }); diff --git a/packages/router/test/int/PendlePtToAsset.eth.spec.ts b/packages/router/test/int/PendlePtToAsset.eth.spec.ts index f97e0462..907815be 100644 --- a/packages/router/test/int/PendlePtToAsset.eth.spec.ts +++ b/packages/router/test/int/PendlePtToAsset.eth.spec.ts @@ -1,6 +1,7 @@ import { expect } from 'chai'; import { ethers } from 'hardhat'; import { + assertSwapEvent, constructSwap, delay, Dex, @@ -533,6 +534,18 @@ describe('PendlePtToAssetAdapter', async () => { const ibtBalanceAfter = await showBalance(assetToken, user.address, 'Asset balance After:'); expect(ibtBalanceBefore.sub(ibtBalanceAfter)).to.be.lessThanOrEqual(ibtTokenAmount); + await assertSwapEvent( + { + amountIn: ibtBalanceBefore.sub(ibtBalanceAfter), + amountOut: ptBalanceAfter.sub(ptBalanceBefore), + isExactInput: true, + tokenIn: assetToken.address, + tokenOut: ptToken.address, + }, + router, + tx + ); + await showBalanceDelta(ptBalanceBefore, ptBalanceAfter, ptToken, 'PT balance delta:'); await showBalanceDelta(ibtBalanceBefore, ibtBalanceAfter, assetToken, 'Asset balance delta:'); await showBalance(syToken, adapter.address, 'sy balance on adapter:'); @@ -557,6 +570,18 @@ describe('PendlePtToAssetAdapter', async () => { const ibtBalanceAfter = await showBalance(assetToken, user.address, 'Asset balance After: '); expect(ibtBalanceBefore).to.be.greaterThan(ibtBalanceAfter); + await assertSwapEvent( + { + amountIn: ibtBalanceBefore.sub(ibtBalanceAfter), + amountOut: ptBalanceAfter.sub(ptBalanceBefore), + isExactInput: false, + tokenIn: assetToken.address, + tokenOut: ptToken.address, + }, + router, + tx + ); + await showBalanceDelta(ptBalanceBefore, ptBalanceAfter, ptToken, 'PT balance delta:'); await showBalanceDelta(ibtBalanceBefore, ibtBalanceAfter, assetToken, 'Asset balance delta:'); await showBalance(syToken, adapter.address, 'sy balance on adapter:'); @@ -581,6 +606,18 @@ describe('PendlePtToAssetAdapter', async () => { const ibtBalanceAfter = await showBalance(assetToken, user.address, 'Asset balance After:'); expect(ibtBalanceAfter).to.be.greaterThan(ibtBalanceBefore); + await assertSwapEvent( + { + amountIn: ptBalanceBefore.sub(ptBalanceAfter), + amountOut: ibtBalanceAfter.sub(ibtBalanceBefore), + isExactInput: true, + tokenIn: ptToken.address, + tokenOut: assetToken.address, + }, + router, + tx + ); + await showBalanceDelta(ptBalanceBefore, ptBalanceAfter, ptToken, 'PT balance delta:'); await showBalanceDelta(ibtBalanceBefore, ibtBalanceAfter, assetToken, 'Asset balance delta:'); await showBalance(syToken, adapter.address, 'sy balance on adapter:'); @@ -605,6 +642,18 @@ describe('PendlePtToAssetAdapter', async () => { const ibtBalanceAfter = await showBalance(assetToken, user.address, 'Asset balance After:'); expect(ibtBalanceAfter.sub(ibtBalanceBefore)).to.be.eq(ibtMinOut); + await assertSwapEvent( + { + amountIn: ptBalanceBefore.sub(ptBalanceAfter), + amountOut: ibtBalanceAfter.sub(ibtBalanceBefore), + isExactInput: false, + tokenIn: ptToken.address, + tokenOut: assetToken.address, + }, + router, + tx + ); + await showBalanceDelta(ptBalanceBefore, ptBalanceAfter, ptToken, 'PT balance delta:'); await showBalanceDelta(ibtBalanceBefore, ibtBalanceAfter, assetToken, 'Asset balance delta:'); await showBalance(syToken, adapter.address, 'sy balance on adapter:'); @@ -685,6 +734,18 @@ describe('PendlePtToAssetAdapter', async () => { const ibtBalanceAfter = await showBalance(assetToken, user.address, 'Asset balance After:'); expect(ibtBalanceAfter).to.be.greaterThan(ibtBalanceBefore); + await assertSwapEvent( + { + amountIn: ptBalanceBefore.sub(ptBalanceAfter), + amountOut: ibtBalanceAfter.sub(ibtBalanceBefore), + isExactInput: true, + tokenIn: ptToken.address, + tokenOut: assetToken.address, + }, + router, + tx + ); + await showBalanceDelta(ptBalanceBefore, ptBalanceAfter, ptToken, 'PT balance delta:'); await showBalanceDelta(ibtBalanceBefore, ibtBalanceAfter, assetToken, 'Asset balance delta:'); await showBalance(syToken, adapter.address, 'sy balance on adapter:'); @@ -709,6 +770,18 @@ describe('PendlePtToAssetAdapter', async () => { const ibtBalanceAfter = await showBalance(assetToken, user.address, 'Asset balance After:'); expect(ibtBalanceAfter.sub(ibtBalanceBefore)).to.be.eq(ibtOut); + await assertSwapEvent( + { + amountIn: ptBalanceBefore.sub(ptBalanceAfter), + amountOut: ibtBalanceAfter.sub(ibtBalanceBefore), + isExactInput: false, + tokenIn: ptToken.address, + tokenOut: assetToken.address, + }, + router, + tx + ); + await showBalanceDelta(ptBalanceBefore, ptBalanceAfter, ptToken, 'PT balance delta:'); await showBalanceDelta(ibtBalanceBefore, ibtBalanceAfter, assetToken, 'Asset balance delta:'); await showBalance(syToken, adapter.address, 'sy balance on adapter:'); diff --git a/packages/router/test/int/SpectraAdapter.eth.spec.ts b/packages/router/test/int/SpectraAdapter.eth.spec.ts index dd9ae371..531f9b49 100644 --- a/packages/router/test/int/SpectraAdapter.eth.spec.ts +++ b/packages/router/test/int/SpectraAdapter.eth.spec.ts @@ -8,6 +8,7 @@ import { SpectraAdapter__factory, } from '../../typechain-types'; import { + assertSwapEvent, constructSwap, delay, Dex, @@ -459,6 +460,18 @@ describe('SpectraAdapter', async () => { const ibtBalanceAfter = await showBalance(ibtToken, user.address, 'ibt balance After:'); expect(ibtBalanceBefore.sub(ibtBalanceAfter)).to.be.lessThanOrEqual(ibtTokenAmount); + await assertSwapEvent( + { + amountIn: ibtBalanceBefore.sub(ibtBalanceAfter), + amountOut: ptBalanceAfter.sub(ptBalanceBefore), + isExactInput: true, + tokenIn: ibtToken.address, + tokenOut: ptToken.address, + }, + router, + tx + ); + await showBalanceDelta(ptBalanceBefore, ptBalanceAfter, ptToken, 'PT balance delta:'); await showBalanceDelta(ibtBalanceBefore, ibtBalanceAfter, ibtToken, 'IBT balance delta:'); }); @@ -481,6 +494,18 @@ describe('SpectraAdapter', async () => { const ibtBalanceAfter = await showBalance(ibtToken, user.address, 'ibt balance After: '); expect(ibtBalanceBefore).to.be.greaterThan(ibtBalanceAfter); + await assertSwapEvent( + { + amountIn: ibtBalanceBefore.sub(ibtBalanceAfter), + amountOut: ptBalanceAfter.sub(ptBalanceBefore), + isExactInput: false, + tokenIn: ibtToken.address, + tokenOut: ptToken.address, + }, + router, + tx + ); + await showBalanceDelta(ptBalanceBefore, ptBalanceAfter, ptToken, 'PT balance delta:'); await showBalanceDelta(ibtBalanceBefore, ibtBalanceAfter, ibtToken, 'IBT balance delta:'); }); @@ -503,6 +528,18 @@ describe('SpectraAdapter', async () => { const ibtBalanceAfter = await showBalance(ibtToken, user.address, 'ibt balance After:'); expect(ibtBalanceAfter).to.be.greaterThan(ibtBalanceBefore); + await assertSwapEvent( + { + amountIn: ptBalanceBefore.sub(ptBalanceAfter), + amountOut: ibtBalanceAfter.sub(ibtBalanceBefore), + isExactInput: true, + tokenIn: ptToken.address, + tokenOut: ibtToken.address, + }, + router, + tx + ); + await showBalanceDelta(ptBalanceBefore, ptBalanceAfter, ptToken, 'PT balance delta:'); await showBalanceDelta(ibtBalanceBefore, ibtBalanceAfter, ibtToken, 'IBT balance delta:'); }); @@ -525,6 +562,18 @@ describe('SpectraAdapter', async () => { const ibtBalanceAfter = await showBalance(ibtToken, user.address, 'ibt balance After:'); expect(ibtBalanceAfter.sub(ibtBalanceBefore)).to.be.eq(ibtMinOut); + await assertSwapEvent( + { + amountIn: ptBalanceBefore.sub(ptBalanceAfter), + amountOut: ibtBalanceAfter.sub(ibtBalanceBefore), + isExactInput: false, + tokenIn: ptToken.address, + tokenOut: ibtToken.address, + }, + router, + tx + ); + await showBalanceDelta(ptBalanceBefore, ptBalanceAfter, ptToken, 'PT balance delta:'); await showBalanceDelta(ibtBalanceBefore, ibtBalanceAfter, ibtToken, 'IBT balance delta:'); }); @@ -602,6 +651,18 @@ describe('SpectraAdapter', async () => { const ibtBalanceAfter = await showBalance(ibtToken, user.address, 'ibt balance After:'); expect(ibtBalanceAfter).to.be.greaterThan(ibtBalanceBefore); + await assertSwapEvent( + { + amountIn: ptBalanceBefore.sub(ptBalanceAfter), + amountOut: ibtBalanceAfter.sub(ibtBalanceBefore), + isExactInput: true, + tokenIn: ptToken.address, + tokenOut: ibtToken.address, + }, + router, + tx + ); + await showBalanceDelta(ptBalanceBefore, ptBalanceAfter, ptToken, 'PT balance delta:'); await showBalanceDelta(ibtBalanceBefore, ibtBalanceAfter, ibtToken, 'IBT balance delta:'); }); @@ -624,6 +685,18 @@ describe('SpectraAdapter', async () => { const ibtBalanceAfter = await showBalance(ibtToken, user.address, 'ibt balance After:'); expect(ibtBalanceAfter.sub(ibtBalanceBefore)).to.be.eq(ibtOut); + await assertSwapEvent( + { + amountIn: ptBalanceBefore.sub(ptBalanceAfter), + amountOut: ibtBalanceAfter.sub(ibtBalanceBefore), + isExactInput: false, + tokenIn: ptToken.address, + tokenOut: ibtToken.address, + }, + router, + tx + ); + await showBalanceDelta(ptBalanceBefore, ptBalanceAfter, ptToken, 'PT balance delta:'); await showBalanceDelta(ibtBalanceBefore, ibtBalanceAfter, ibtToken, 'IBT balance delta:'); }); diff --git a/packages/router/test/shared/utils.ts b/packages/router/test/shared/utils.ts index c00edf5e..ba079235 100644 --- a/packages/router/test/shared/utils.ts +++ b/packages/router/test/shared/utils.ts @@ -1,8 +1,10 @@ import { BigNumber, ContractTransaction } from 'ethers'; -import { ERC20 } from '../../typechain-types'; +import { ERC20, MarginlyRouter } from '../../typechain-types'; import { formatUnits } from 'ethers/lib/utils'; import { reset } from '@nomicfoundation/hardhat-network-helpers'; import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { SwapEvent } from '../../typechain-types/contracts/interfaces/IMarginlyRouter'; +import { expect } from 'chai'; const hre = require('hardhat'); export const SWAP_ONE = 1 << 15; @@ -80,3 +82,39 @@ export async function resetFork(blockNumber?: number) { export function delay(ms: number) { return new Promise((resolve) => setTimeout(resolve, ms)); } + +export async function assertSwapEvent( + expectedValues: { + isExactInput: boolean; + amountIn: BigNumber; + amountOut: BigNumber; + tokenIn: string; + tokenOut: string; + }, + router: MarginlyRouter, + tx: any +) { + const swapEvent = await getSwapEvent(router, tx); + expect(swapEvent.args.isExactInput).to.be.eq(expectedValues.isExactInput); + expect(swapEvent.args.amountIn).to.be.eq(expectedValues.amountIn); + expect(swapEvent.args.amountOut).to.be.eq(expectedValues.amountOut); + expect(swapEvent.args.tokenIn.toLocaleLowerCase()).to.be.eq(expectedValues.tokenIn.toLocaleLowerCase()); + expect(swapEvent.args.tokenOut.toLocaleLowerCase()).to.be.eq(expectedValues.tokenOut.toLocaleLowerCase()); +} + +async function getSwapEvent(router: MarginlyRouter, tx: any): Promise { + const eventFilter = router.filters['Swap(bool,uint256,address,address,address,uint256,uint256)']( + null, + null, + null, + null, + null, + null + ); + const events = await router.queryFilter(eventFilter, tx.blockHash); + expect(events.length).to.be.eq(1); + const swapEvent = events[0]; + + expect(swapEvent).to.not.be.undefined; + return swapEvent; +} diff --git a/packages/timelock/tasks/timelock.ts b/packages/timelock/tasks/timelock.ts index cbf2891c..bdada69a 100644 --- a/packages/timelock/tasks/timelock.ts +++ b/packages/timelock/tasks/timelock.ts @@ -110,13 +110,13 @@ taskWithSigner('factory-transfer-ownership', 'Change factory owner to timelock') } ); -//npx hardhat --network holesky --config hardhat.config.ts timelock-execute --signer +//npx hardhat --network ethereum --config hardhat.config.ts timelock-execute --keystore path-to-keystore-file taskWithSigner('timelock-execute', 'Timelock schedule and execute operation').setAction( async (taskArgs: SignerArgs, hre: HardhatRuntimeEnvironment) => { //@ts-ignore const signer = await getSigner(taskArgs, hre.ethers.provider); - const timelockAddress = '0xc71968f413bF7EDa0d11629e0Cedca0831967cD3'; + const timelockAddress = '0x8cDAf202eBe2f38488074DcFCa08c0B0cB7B8Aa5'; const timelock = TimelockWhitelist__factory.connect(timelockAddress, signer); const predecessor = ethers.ZeroHash;