From d08cbf608129af05e627ff5ae303f9f1c2e96595 Mon Sep 17 00:00:00 2001 From: Andrew Chiaramonte Date: Fri, 21 Feb 2025 10:00:04 -0500 Subject: [PATCH 01/24] =?UTF-8?q?=F0=9F=91=B7=20zapIn=20and=20zapOut=20in?= =?UTF-8?q?=20zap?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Zap.sol | 79 ++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 69 insertions(+), 10 deletions(-) diff --git a/src/Zap.sol b/src/Zap.sol index 099a727..aa9b55e 100644 --- a/src/Zap.sol +++ b/src/Zap.sol @@ -3,6 +3,7 @@ pragma solidity 0.8.27; import {IPool} from "./interfaces/IAave.sol"; import {IERC20} from "./interfaces/IERC20.sol"; +import {IERC4626} from "./interfaces/IERC4626.sol"; import {IPerpsMarket, ISpotMarket} from "./interfaces/ISynthetix.sol"; import {Errors} from "./utils/Errors.sol"; @@ -34,10 +35,13 @@ contract Zap is Reentrancy, Errors, Flush(msg.sender) { address public immutable PERPS_MARKET; address public immutable REFERRER; uint128 public immutable SUSDC_SPOT_ID; + uint128 public immutable SSTATA_SPOT_ID; + address public immutable SSTATA; /// @custom:aave uint16 public constant REFERRAL_CODE = 0; address public immutable AAVE; + address public immutable STATA; /// @custom:odos address public immutable ROUTER; @@ -45,11 +49,14 @@ contract Zap is Reentrancy, Errors, Flush(msg.sender) { constructor( address _usdc, address _usdx, + address _sstata, address _spotMarket, address _perpsMarket, address _referrer, uint128 _susdcSpotId, + uint128 _sstataSpotId, address _aave, + address _stata, address _router ) { /// @custom:circle @@ -57,13 +64,16 @@ contract Zap is Reentrancy, Errors, Flush(msg.sender) { /// @custom:synthetix USDX = _usdx; + SSTATA = _sstata; SPOT_MARKET = _spotMarket; PERPS_MARKET = _perpsMarket; REFERRER = _referrer; SUSDC_SPOT_ID = _susdcSpotId; + SSTATA_SPOT_ID = _sstataSpotId; /// @custom:aave AAVE = _aave; + STATA = _stata; /// @custom:odos ROUTER = _router; @@ -93,12 +103,12 @@ contract Zap is Reentrancy, Errors, Flush(msg.sender) { ZAP //////////////////////////////////////////////////////////////*/ - /// @notice zap USDC into USDx + /// @notice zap USDC into STATA /// @dev caller must grant USDC allowance to this contract /// @param _amount amount of USDC to zap /// @param _minAmountOut acceptable slippage for wrapping and selling - /// @param _receiver address to receive USDx - /// @return zapped amount of USDx received + /// @param _receiver address to receive STATA + /// @return zapped amount of STATA received function zapIn( uint256 _amount, uint256 _minAmountOut, @@ -109,17 +119,30 @@ contract Zap is Reentrancy, Errors, Flush(msg.sender) { { _pull(USDC, msg.sender, _amount); zapped = _zapIn(_amount, _minAmountOut); - _push(USDX, _receiver, zapped); + _push(SSTATA, _receiver, zapped); } /// @dev allowance is assumed - /// @dev following execution, this contract will hold the zapped USDx + /// @dev following execution, this contract will hold the zapped STATA function _zapIn( uint256 _amount, uint256 _minAmountOut ) internal returns (uint256 zapped) + { + zapped = _depositStata(_amount, address(this)); + zapped = _wrap(STATA, SSTATA_SPOT_ID, zapped, _minAmountOut); + } + + /// @dev allowance is assumed + /// @dev following execution, this contract will hold the zapped USDx + function _zapInUSDx( + uint256 _amount, + uint256 _minAmountOut + ) + internal + returns (uint256 zapped) { zapped = _wrap(USDC, SUSDC_SPOT_ID, _amount, _minAmountOut); zapped = _sell(SUSDC_SPOT_ID, zapped, _minAmountOut); @@ -139,7 +162,7 @@ contract Zap is Reentrancy, Errors, Flush(msg.sender) { external returns (uint256 zapped) { - _pull(USDX, msg.sender, _amount); + _pull(SSTATA, msg.sender, _amount); zapped = _zapOut(_amount, _minAmountOut); _push(USDC, _receiver, zapped); } @@ -153,8 +176,42 @@ contract Zap is Reentrancy, Errors, Flush(msg.sender) { internal returns (uint256 zapped) { - zapped = _buy(SUSDC_SPOT_ID, _amount, _minAmountOut); - zapped = _unwrap(SUSDC_SPOT_ID, zapped, _minAmountOut); + zapped = _unwrap(SSTATA_SPOT_ID, _amount, _minAmountOut); + zapped = _redeemStata(zapped, address(this)); + } + + /// @dev allowance is assumed + /// @dev following execution, this contract will hold the zapped USDC + function _zapOutUSDx( + uint256 _amount, + uint256 _minAmountOut + ) + internal + returns (uint256 zapped) + { + zapped = _buy(SSTATA_SPOT_ID, _amount, _minAmountOut); + zapped = _unwrap(SSTATA_SPOT_ID, zapped, _minAmountOut); + } + + /*////////////////////////////////////////////////////////////// + STATA DEPOSIT AND WITHDRAW + //////////////////////////////////////////////////////////////*/ + + /// @notice deposit STATA + /// @param _amount amount of STATA to deposit + /// @param _receiver address to receive deposited STATA + /// @return shares received + function _depositStata(uint256 _amount, address _receiver) internal returns (uint256 shares) { + IERC20(USDC).approve(STATA, _amount); + shares = IERC4626(STATA).deposit(_amount, _receiver); + } + + /// @notice redeem STATA + /// @param _shares amount of STATA to redeem + /// @param _receiver address to receive redeemed STATA + /// @return assets received + function _redeemStata(uint256 _shares, address _receiver) internal returns (uint256 assets) { + assets = IERC4626(STATA).redeem(_shares, _receiver, _receiver); } /*////////////////////////////////////////////////////////////// @@ -479,7 +536,7 @@ contract Zap is Reentrancy, Errors, Flush(msg.sender) { // zap USDC from flashloan into USDx; // ALL USDC flashloaned from Aave is zapped into USDx - uint256 usdxAmount = _zapIn(_flashloan, _zapMinAmountOut); + uint256 usdxAmount = _zapInUSDx(_flashloan, _zapMinAmountOut); // burn USDx to pay off synthetix perp position debt; // debt is denominated in USD and thus repaid with USDx @@ -493,7 +550,9 @@ contract Zap is Reentrancy, Errors, Flush(msg.sender) { _withdraw(_collateralId, _collateralAmount, _accountId); if (_collateral == USDC && _collateralId == USDX_ID) { - unwound = _zapOut(_collateralAmount, _collateralAmount / 1e12); + unwound = _zapOutUSDx(_collateralAmount, _collateralAmount / 1e12); + } else if (_collateral == STATA && _collateralId == SSTATA_SPOT_ID) { + unwound = _zapOut(_collateralAmount, _unwrapMinAmountOut); } else { // unwrap withdrawn synthetix perp position collateral; // i.e., sETH -> WETH, sUSDe -> USDe, sUSDC -> USDC (...) From 4cb687f861d5e654fb68d4b78d7ada92c7404991 Mon Sep 17 00:00:00 2001 From: Andrew Chiaramonte Date: Fri, 21 Feb 2025 10:00:50 -0500 Subject: [PATCH 02/24] =?UTF-8?q?=F0=9F=9A=80=20add=20new=20params=20to=20?= =?UTF-8?q?deployment?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- script/Deploy.s.sol | 15 +++++++++++++++ script/utils/Parameters.sol | 3 +++ 2 files changed, 18 insertions(+) diff --git a/script/Deploy.s.sol b/script/Deploy.s.sol index 636435b..fa75c20 100644 --- a/script/Deploy.s.sol +++ b/script/Deploy.s.sol @@ -20,11 +20,14 @@ contract Deploy is Script { function deploySystem( address usdc, address usdx, + address sstata, address spotMarket, address perpsMarket, address referrer, uint128 susdcSpotId, + uint128 sstataSpotId, address aave, + address stata, address router ) public @@ -33,11 +36,14 @@ contract Deploy is Script { zap = new Zap({ _usdc: usdc, _usdx: usdx, + _sstata: sstata, _spotMarket: spotMarket, _perpsMarket: perpsMarket, _referrer: referrer, _susdcSpotId: susdcSpotId, + _sstataSpotId: sstataSpotId, _aave: aave, + _stata: stata, _router: router }); } @@ -51,11 +57,14 @@ contract DeployBase is Deploy, Base { Zap zap = deploySystem({ usdc: BASE_USDC, usdx: BASE_USDX, + sstata: BASE_SSTATA, spotMarket: BASE_SPOT_MARKET, perpsMarket: BASE_PERPS_MARKET, referrer: BASE_REFERRER, susdcSpotId: BASE_SUSDC_SPOT_MARKET_ID, + sstataSpotId: BASE_SSTATA_SPOT_MARKET_ID, aave: BASE_AAVE_POOL, + stata: BASE_STATA, router: BASE_ROUTER }); // PDAO will have to accept Nomination @@ -71,11 +80,14 @@ contract DeployArbitrum is Deploy, Arbitrum { Zap zap = deploySystem({ usdc: ARBITRUM_USDC, usdx: ARBITRUM_USDX, + sstata: address(0), //todo we are not deploying this stata release to arbitrum spotMarket: ARBITRUM_SPOT_MARKET, perpsMarket: ARBITRUM_PERPS_MARKET, referrer: ARBITRUM_REFERRER, susdcSpotId: ARBITRUM_SUSDC_SPOT_MARKET_ID, + sstataSpotId: 0, //todo we are not deploying this stata release to arbitrum aave: ARBITRUM_AAVE_POOL, + stata: address(0), //todo we are not deploying this stata release to arbitrum router: ARBITRUM_ROUTER }); Flush(address(zap)).nominatePlumber(ARBITRUM_PDAO); @@ -90,11 +102,14 @@ contract DeployArbitrumSepolia is Deploy, ArbitrumSepolia { Zap zap = deploySystem({ usdc: ARBITRUM_SEPOLIA_USDC, usdx: ARBITRUM_SEPOLIA_USDX, + sstata: address(0), //todo we are not deploying this stata release to arbitrum spotMarket: ARBITRUM_SEPOLIA_SPOT_MARKET, perpsMarket: ARBITRUM_SEPOLIA_PERPS_MARKET, referrer: ARBITRUM_SEPOLIA_REFERRER, susdcSpotId: ARBITRUM_SEPOLIA_SUSDC_SPOT_MARKET_ID, + sstataSpotId: 0, //todo we are not deploying this stata release to arbitrum aave: ARBITRUM_SEPOLIA_AAVE_POOL, + stata: address(0), //todo we are not deploying this stata release to arbitrum router: ARBITRUM_SEPOLIA_ROUTER }); Flush(address(zap)).nominatePlumber(ARBITRUM_SEPOLIA_PDAO); diff --git a/script/utils/Parameters.sol b/script/utils/Parameters.sol index c17f72d..27e9ff1 100644 --- a/script/utils/Parameters.sol +++ b/script/utils/Parameters.sol @@ -9,13 +9,16 @@ contract Base { /// @custom:synthetix address BASE_USDC = 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913; address BASE_USDX = 0x09d51516F38980035153a554c26Df3C6f51a23C3; + address BASE_SSTATA = 0x729Ef31D86d31440ecBF49f27F7cD7c16c6616d2; address BASE_SPOT_MARKET = 0x18141523403e2595D31b22604AcB8Fc06a4CaA61; address BASE_PERPS_MARKET = 0x0A2AF931eFFd34b81ebcc57E3d3c9B1E1dE1C9Ce; address BASE_REFERRER = address(0); uint128 BASE_SUSDC_SPOT_MARKET_ID = 1; + uint128 BASE_SSTATA_SPOT_MARKET_ID = 3; /// @custom:aave address BASE_AAVE_POOL = 0xA238Dd80C259a72e81d7e4664a9801593F98d1c5; + address BASE_STATA = 0x4EA71A20e655794051D1eE8b6e4A3269B13ccaCc; /// @custom:odos address BASE_ROUTER = 0x19cEeAd7105607Cd444F5ad10dd51356436095a1; From eb7f69d8521149ef2c0448826293a737e35f07fc Mon Sep 17 00:00:00 2001 From: Andrew Chiaramonte Date: Fri, 21 Feb 2025 10:03:28 -0500 Subject: [PATCH 03/24] =?UTF-8?q?=F0=9F=93=9A=20author=20tag?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Zap.sol | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Zap.sol b/src/Zap.sol index aa9b55e..5169b04 100644 --- a/src/Zap.sol +++ b/src/Zap.sol @@ -21,6 +21,7 @@ import {SafeERC20} from "./utils/SafeTransferERC20.sol"; /// @author @flocqst /// @author @barrasso /// @author @moss-eth +/// @author @cmontecoding contract Zap is Reentrancy, Errors, Flush(msg.sender) { /// @custom:circle From d613189fbe8b7778fc955c1cc581ba6e0e089146 Mon Sep 17 00:00:00 2001 From: Andrew Chiaramonte Date: Fri, 21 Feb 2025 10:03:40 -0500 Subject: [PATCH 04/24] =?UTF-8?q?=F0=9F=91=B7=20vault=20interface?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/interfaces/IERC4626.sol | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/interfaces/IERC4626.sol diff --git a/src/interfaces/IERC4626.sol b/src/interfaces/IERC4626.sol new file mode 100644 index 0000000..a1dabb1 --- /dev/null +++ b/src/interfaces/IERC4626.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.27; + +interface IERC4626 { + + function approve(address spender, uint256 amount) external returns (bool); + + function deposit( + uint256 assets, + address receiver + ) + external + returns (uint256 shares); + + function redeem( + uint256 shares, + address receiver, + address owner + ) + external + returns (uint256 assets); + +} From 4b6c96f8ea57b11d0d901f36ab5f233c998ad92c Mon Sep 17 00:00:00 2001 From: Andrew Chiaramonte Date: Fri, 21 Feb 2025 10:05:07 -0500 Subject: [PATCH 05/24] =?UTF-8?q?=E2=9C=85=20zap=20in=20and=20out=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/Zap.in.t.sol | 35 +++++++++++++++++---------------- test/Zap.out.t.sol | 48 +++++++++++++++++++++++++++++----------------- 2 files changed, 48 insertions(+), 35 deletions(-) diff --git a/test/Zap.in.t.sol b/test/Zap.in.t.sol index 5807fa5..97bf065 100644 --- a/test/Zap.in.t.sol +++ b/test/Zap.in.t.sol @@ -16,7 +16,7 @@ contract ZapInTest is Bootstrap { function test_zap_in_base(uint32 amount) public base { _spin(ACTOR, usdc, amount, address(zap)); assertEq(usdc.balanceOf(ACTOR), amount); - assertEq(usdx.balanceOf(ACTOR), 0); + assertEq(sstata.balanceOf(ACTOR), 0); vm.startPrank(ACTOR); uint256 zapped = zap.zapIn({ _amount: amount, @@ -26,23 +26,24 @@ contract ZapInTest is Bootstrap { vm.stopPrank(); assertGe(zapped, DEFAULT_MIN_AMOUNT_OUT); assertEq(usdc.balanceOf(ACTOR), 0); - assertEq(usdx.balanceOf(ACTOR), zapped); + assertEq(sstata.balanceOf(ACTOR), zapped); } - function test_zap_in_arbitrum(uint32 amount) public arbitrum { - _spin(ACTOR, usdc, amount, address(zap)); - assertEq(usdc.balanceOf(ACTOR), amount); - assertEq(usdx.balanceOf(ACTOR), 0); - vm.startPrank(ACTOR); - uint256 zapped = zap.zapIn({ - _amount: amount, - _minAmountOut: DEFAULT_MIN_AMOUNT_OUT, - _receiver: ACTOR - }); - vm.stopPrank(); - assertGe(zapped, DEFAULT_MIN_AMOUNT_OUT); - assertEq(usdc.balanceOf(ACTOR), 0); - assertEq(usdx.balanceOf(ACTOR), zapped); - } + /// @custom:disabled no stata on arbitrum + // function test_zap_in_arbitrum(uint32 amount) public arbitrum { + // _spin(ACTOR, usdc, amount, address(zap)); + // assertEq(usdc.balanceOf(ACTOR), amount); + // assertEq(usdx.balanceOf(ACTOR), 0); + // vm.startPrank(ACTOR); + // uint256 zapped = zap.zapIn({ + // _amount: amount, + // _minAmountOut: DEFAULT_MIN_AMOUNT_OUT, + // _receiver: ACTOR + // }); + // vm.stopPrank(); + // assertGe(zapped, DEFAULT_MIN_AMOUNT_OUT); + // assertEq(usdc.balanceOf(ACTOR), 0); + // assertEq(usdx.balanceOf(ACTOR), zapped); + // } } diff --git a/test/Zap.out.t.sol b/test/Zap.out.t.sol index e2b3ab1..9a10591 100644 --- a/test/Zap.out.t.sol +++ b/test/Zap.out.t.sol @@ -13,38 +13,50 @@ import { contract ZapOutTest is Bootstrap { - function test_zap_out_base(uint64 amount) public base { - vm.assume(amount > 1e18); - _spin(ACTOR, usdx, amount, address(zap)); - assertEq(usdc.balanceOf(ACTOR), 0); - assertEq(usdx.balanceOf(ACTOR), amount); + function test_zap_out_base(uint32 amount) public base { + /// @dev setup by zapping in because + /// cant _spin sstata + _spin(ACTOR, usdc, amount, address(zap)); + assertEq(usdc.balanceOf(ACTOR), amount); + assertEq(sstata.balanceOf(ACTOR), 0); vm.startPrank(ACTOR); - uint256 zapped = zap.zapOut({ + uint256 zapped = zap.zapIn({ _amount: amount, _minAmountOut: DEFAULT_MIN_AMOUNT_OUT, _receiver: ACTOR }); - vm.stopPrank(); - assertGe(zapped, DEFAULT_MIN_AMOUNT_OUT); - assertEq(usdc.balanceOf(ACTOR), zapped); - assertEq(usdx.balanceOf(ACTOR), 0); - } - function test_zap_out_arbitum(uint64 amount) public arbitrum { - vm.assume(amount > 1e18); - _spin(ACTOR, usdx, amount, address(zap)); assertEq(usdc.balanceOf(ACTOR), 0); - assertEq(usdx.balanceOf(ACTOR), amount); + assertEq(sstata.balanceOf(ACTOR), zapped); vm.startPrank(ACTOR); - uint256 zapped = zap.zapOut({ - _amount: amount, + sstata.approve(address(zap), zapped); + zapped = zap.zapOut({ + _amount: zapped, _minAmountOut: DEFAULT_MIN_AMOUNT_OUT, _receiver: ACTOR }); vm.stopPrank(); assertGe(zapped, DEFAULT_MIN_AMOUNT_OUT); assertEq(usdc.balanceOf(ACTOR), zapped); - assertEq(usdx.balanceOf(ACTOR), 0); + assertEq(sstata.balanceOf(ACTOR), 0); } + /// @custom:disabled no stata on arbitrum + // function test_zap_out_arbitum(uint64 amount) public arbitrum { + // vm.assume(amount > 1e18); + // _spin(ACTOR, usdx, amount, address(zap)); + // assertEq(usdc.balanceOf(ACTOR), 0); + // assertEq(usdx.balanceOf(ACTOR), amount); + // vm.startPrank(ACTOR); + // uint256 zapped = zap.zapOut({ + // _amount: amount, + // _minAmountOut: DEFAULT_MIN_AMOUNT_OUT, + // _receiver: ACTOR + // }); + // vm.stopPrank(); + // assertGe(zapped, DEFAULT_MIN_AMOUNT_OUT); + // assertEq(usdc.balanceOf(ACTOR), zapped); + // assertEq(usdx.balanceOf(ACTOR), 0); + // } + } From 0bae5a18d00e5b027ec280547353e9c6209a1495 Mon Sep 17 00:00:00 2001 From: Andrew Chiaramonte Date: Fri, 21 Feb 2025 10:05:15 -0500 Subject: [PATCH 06/24] =?UTF-8?q?=E2=9C=85=20bootstrap?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/utils/Bootstrap.sol | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/test/utils/Bootstrap.sol b/test/utils/Bootstrap.sol index 1c2e435..e2231b2 100644 --- a/test/utils/Bootstrap.sol +++ b/test/utils/Bootstrap.sol @@ -40,6 +40,7 @@ contract Bootstrap is IERC20 usdc; IERC20 susdc; IERC20 usdx; + IERC20 sstata; IERC20 weth; IERC20 tbtc; @@ -67,11 +68,14 @@ contract Bootstrap is zap = deploySystem({ usdc: BASE_USDC, usdx: BASE_USDX, + sstata: BASE_SSTATA, spotMarket: BASE_SPOT_MARKET, perpsMarket: BASE_PERPS_MARKET, referrer: BASE_REFERRER, susdcSpotId: BASE_SUSDC_SPOT_MARKET_ID, + sstataSpotId: BASE_SSTATA_SPOT_MARKET_ID, aave: BASE_AAVE_POOL, + stata: BASE_STATA, router: BASE_ROUTER }); @@ -79,8 +83,9 @@ contract Bootstrap is spotMarket = ISpotMarket(BASE_SPOT_MARKET); perpsMarket = IPerpsMarket(BASE_PERPS_MARKET); usdc = IERC20(BASE_USDC); - susdc = IERC20(spotMarket.getSynth(zap.SUSDC_SPOT_ID())); + susdc = IERC20(spotMarket.getSynth(zap.SSTATA_SPOT_ID())); usdx = IERC20(BASE_USDX); + sstata = IERC20(BASE_SSTATA); weth = IERC20(BASE_WETH); tbtc = IERC20(BASE_TBTC); @@ -95,11 +100,14 @@ contract Bootstrap is zap = deploySystem({ usdc: ARBITRUM_USDC, usdx: ARBITRUM_USDX, + sstata: address(0), //todo we are not deploying this stata release to arbitrum spotMarket: ARBITRUM_SPOT_MARKET, perpsMarket: ARBITRUM_PERPS_MARKET, referrer: ARBITRUM_REFERRER, susdcSpotId: ARBITRUM_SUSDC_SPOT_MARKET_ID, + sstataSpotId: 0, //todo we are not deploying this stata release to arbitrum aave: ARBITRUM_AAVE_POOL, + stata: address(0), //todo we are not deploying this stata release to arbitrum router: ARBITRUM_ROUTER }); @@ -107,7 +115,7 @@ contract Bootstrap is spotMarket = ISpotMarket(ARBITRUM_SPOT_MARKET); perpsMarket = IPerpsMarket(ARBITRUM_PERPS_MARKET); usdc = IERC20(ARBITRUM_USDC); - susdc = IERC20(spotMarket.getSynth(zap.SUSDC_SPOT_ID())); + susdc = IERC20(spotMarket.getSynth(zap.SSTATA_SPOT_ID())); usdx = IERC20(ARBITRUM_USDX); weth = IERC20(ARBITRUM_WETH); tbtc = IERC20(ARBITRUM_TBTC); @@ -122,11 +130,14 @@ contract Bootstrap is zap = deploySystem({ usdc: ARBITRUM_SEPOLIA_USDC, usdx: ARBITRUM_SEPOLIA_USDX, + sstata: address(0), //todo we are not deploying this stata release to arbitrum spotMarket: ARBITRUM_SEPOLIA_SPOT_MARKET, perpsMarket: ARBITRUM_SEPOLIA_PERPS_MARKET, referrer: ARBITRUM_SEPOLIA_REFERRER, susdcSpotId: ARBITRUM_SEPOLIA_SUSDC_SPOT_MARKET_ID, + sstataSpotId: 0, //todo we are not deploying this stata release to arbitrum aave: ARBITRUM_SEPOLIA_AAVE_POOL, + stata: address(0), //todo we are not deploying this stata release to arbitrum router: ARBITRUM_SEPOLIA_ROUTER }); @@ -134,7 +145,7 @@ contract Bootstrap is spotMarket = ISpotMarket(ARBITRUM_SEPOLIA_SPOT_MARKET); perpsMarket = IPerpsMarket(ARBITRUM_SEPOLIA_PERPS_MARKET); usdc = IERC20(ARBITRUM_SEPOLIA_USDC); - susdc = IERC20(spotMarket.getSynth(zap.SUSDC_SPOT_ID())); + susdc = IERC20(spotMarket.getSynth(zap.SSTATA_SPOT_ID())); usdx = IERC20(ARBITRUM_SEPOLIA_USDX); weth = IERC20(ARBITRUM_SEPOLIA_WETH); From 9ae3f3818fdfdd7899fc16e7f40c3ef8a6c7f3d0 Mon Sep 17 00:00:00 2001 From: Andrew Chiaramonte Date: Fri, 21 Feb 2025 10:05:29 -0500 Subject: [PATCH 07/24] =?UTF-8?q?=E2=9C=85=20update=20block=20number?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/utils/Constants.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/utils/Constants.sol b/test/utils/Constants.sol index 92ae830..5e6a9cf 100644 --- a/test/utils/Constants.sol +++ b/test/utils/Constants.sol @@ -19,7 +19,7 @@ contract Constants { string constant ARBITRUM_RPC_REF = "ARBITRUM_RPC"; string constant ARBITRUM_SEPOLIA_RPC_REF = "ARBITRUM_SEPOLIA_RPC"; - uint256 constant BASE_FORK_BLOCK = 20_165_000; + uint256 constant BASE_FORK_BLOCK = 26_606_911; uint256 constant ARBITRUM_FORK_BLOCK = 256_615_000; uint256 constant ARBITRUM_SEPOLIA_FORK_BLOCK = 85_443_000; From 0294cc66d432b3e1b89af45ea511d3594ce70330 Mon Sep 17 00:00:00 2001 From: Andrew Chiaramonte Date: Fri, 21 Feb 2025 10:28:01 -0500 Subject: [PATCH 08/24] =?UTF-8?q?=E2=9C=85=20fix=20spot=20id=20in=20bootst?= =?UTF-8?q?rap?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/utils/Bootstrap.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/utils/Bootstrap.sol b/test/utils/Bootstrap.sol index e2231b2..76f120a 100644 --- a/test/utils/Bootstrap.sol +++ b/test/utils/Bootstrap.sol @@ -83,7 +83,7 @@ contract Bootstrap is spotMarket = ISpotMarket(BASE_SPOT_MARKET); perpsMarket = IPerpsMarket(BASE_PERPS_MARKET); usdc = IERC20(BASE_USDC); - susdc = IERC20(spotMarket.getSynth(zap.SSTATA_SPOT_ID())); + susdc = IERC20(spotMarket.getSynth(zap.SUSDC_SPOT_ID())); usdx = IERC20(BASE_USDX); sstata = IERC20(BASE_SSTATA); weth = IERC20(BASE_WETH); From eb43e5e6c1955ede946d0f95bfab7abe123212d8 Mon Sep 17 00:00:00 2001 From: Andrew Chiaramonte Date: Fri, 21 Feb 2025 10:28:30 -0500 Subject: [PATCH 09/24] =?UTF-8?q?=E2=9C=85=20comment=20out=20arbitrum=20te?= =?UTF-8?q?sts=20with=20todos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/Aave.t.sol | 33 +- test/Burn.t.sol | 35 +- test/Buy.t.sol | 35 +- test/EndToEnd.t.sol | 3819 ++++++++++++++++++++-------------------- test/OdosAPITest.t.sol | 41 +- test/Sell.t.sol | 47 +- test/Swap.from.t.sol | 115 +- test/Unwind.t.sol | 75 +- test/Unwrap.t.sol | 51 +- test/Withdraw.t.sol | 54 +- test/Wrap.t.sol | 35 +- 11 files changed, 2178 insertions(+), 2162 deletions(-) diff --git a/test/Aave.t.sol b/test/Aave.t.sol index 164d388..f3dba9f 100644 --- a/test/Aave.t.sol +++ b/test/Aave.t.sol @@ -15,21 +15,22 @@ import { contract AaveTest is Bootstrap, Errors { - function test_executeOperation_only_aave( - address caller, - address a, - uint256 b, - uint256 c, - bytes calldata d - ) - public - arbitrum - { - if (caller != zap.AAVE()) { - vm.prank(caller); - vm.expectRevert(abi.encodeWithSelector(OnlyAave.selector, caller)); - zap.executeOperation(a, b, c, a, d); - } - } + /// @custom:disabled no stata on arbitrum + // function test_executeOperation_only_aave( + // address caller, + // address a, + // uint256 b, + // uint256 c, + // bytes calldata d + // ) + // public + // arbitrum + // { + // if (caller != zap.AAVE()) { + // vm.prank(caller); + // vm.expectRevert(abi.encodeWithSelector(OnlyAave.selector, caller)); + // zap.executeOperation(a, b, c, a, d); + // } + // } } diff --git a/test/Burn.t.sol b/test/Burn.t.sol index 8ea5e5c..7e58eba 100644 --- a/test/Burn.t.sol +++ b/test/Burn.t.sol @@ -16,31 +16,32 @@ import "forge-std/console2.sol"; contract BurnTest is Bootstrap { - /// @custom:todo - ///@notice passes at block 269_610_923 - function test_burn_arbitrum(uint32 amount) public arbitrum { - IERC20 A_USDX = IERC20(ARBITRUM_USDX); - uint128 accountID = 170_141_183_460_469_231_731_687_303_715_884_105_766; + /// @custom:disabled no stata on arbitrum + // /// @custom:todo + // ///@notice passes at block 269_610_923 + // function test_burn_arbitrum(uint32 amount) public arbitrum { + // IERC20 A_USDX = IERC20(ARBITRUM_USDX); + // uint128 accountID = 170_141_183_460_469_231_731_687_303_715_884_105_766; - address accountOwner = 0x12a41a75793b6ac2cdDAF680798BB461a1024a46; + // address accountOwner = 0x12a41a75793b6ac2cdDAF680798BB461a1024a46; - uint256 debt = IPerpsMarket(zap.PERPS_MARKET()).debt(accountID); + // uint256 debt = IPerpsMarket(zap.PERPS_MARKET()).debt(accountID); - vm.assume(amount > 1e6 && amount <= debt); + // vm.assume(amount > 1e6 && amount <= debt); - uint256 balBefore = A_USDX.balanceOf(accountOwner); + // uint256 balBefore = A_USDX.balanceOf(accountOwner); - vm.startPrank(accountOwner); - A_USDX.approve(address(zap), type(uint256).max); + // vm.startPrank(accountOwner); + // A_USDX.approve(address(zap), type(uint256).max); - zap.burn(amount, accountID); + // zap.burn(amount, accountID); - uint256 balAfter = A_USDX.balanceOf(accountOwner); - uint256 debtAfter = IPerpsMarket(zap.PERPS_MARKET()).debt(accountID); + // uint256 balAfter = A_USDX.balanceOf(accountOwner); + // uint256 debtAfter = IPerpsMarket(zap.PERPS_MARKET()).debt(accountID); - assertEq(balAfter, balBefore - amount); - assertEq(debt - amount, debtAfter); - } + // assertEq(balAfter, balBefore - amount); + // assertEq(debt - amount, debtAfter); + // } /// @custom:todo function test_burn_base(uint32 amount) public base {} diff --git a/test/Buy.t.sol b/test/Buy.t.sol index 7e21ad9..05e0fb2 100644 --- a/test/Buy.t.sol +++ b/test/Buy.t.sol @@ -32,22 +32,23 @@ contract BuyTest is Bootstrap { assertGe(susdc.balanceOf(ACTOR), DEFAULT_MIN_AMOUNT_OUT); } - function test_buy_arbitrum(uint32 amount) public arbitrum { - _spin(ACTOR, usdx, amount, address(zap)); - assertEq(usdx.balanceOf(ACTOR), amount); - assertEq(susdc.balanceOf(ACTOR), 0); - vm.startPrank(ACTOR); - (uint256 received, address synth) = zap.buy({ - _synthId: zap.SUSDC_SPOT_ID(), - _amount: amount, - _minAmountOut: DEFAULT_MIN_AMOUNT_OUT, - _receiver: ACTOR - }); - vm.stopPrank(); - assertEq(synth, address(susdc)); - assertGe(received, DEFAULT_MIN_AMOUNT_OUT); - assertEq(usdx.balanceOf(ACTOR), 0); - assertGe(susdc.balanceOf(ACTOR), DEFAULT_MIN_AMOUNT_OUT); - } + /// @custom:disabled no stata on arbitrum + // function test_buy_arbitrum(uint32 amount) public arbitrum { + // _spin(ACTOR, usdx, amount, address(zap)); + // assertEq(usdx.balanceOf(ACTOR), amount); + // assertEq(susdc.balanceOf(ACTOR), 0); + // vm.startPrank(ACTOR); + // (uint256 received, address synth) = zap.buy({ + // _synthId: zap.SUSDC_SPOT_ID(), + // _amount: amount, + // _minAmountOut: DEFAULT_MIN_AMOUNT_OUT, + // _receiver: ACTOR + // }); + // vm.stopPrank(); + // assertEq(synth, address(susdc)); + // assertGe(received, DEFAULT_MIN_AMOUNT_OUT); + // assertEq(usdx.balanceOf(ACTOR), 0); + // assertGe(susdc.balanceOf(ACTOR), DEFAULT_MIN_AMOUNT_OUT); + // } } diff --git a/test/EndToEnd.t.sol b/test/EndToEnd.t.sol index 09cdec4..a581969 100644 --- a/test/EndToEnd.t.sol +++ b/test/EndToEnd.t.sol @@ -1,2008 +1,2013 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.27; - -import {Arbitrum} from "../script/utils/Parameters.sol"; -import {IERC20, Zap} from "../src/Zap.sol"; -import {Flush} from "../src/utils/Flush.sol"; -import "./interfaces/ISynthetix.sol"; - -import {Bootstrap} from "./utils/Bootstrap.sol"; -import {Constants} from "./utils/Constants.sol"; -import {OdosSwapData} from "./utils/OdosSwapData.sol"; -import "forge-std/Test.sol"; - -interface IPyth { - - struct PythPrice { - // Price - int64 price; - // Confidence interval around the price - uint64 conf; - // Price exponent - int32 expo; - // Unix timestamp describing when the price was published - uint256 publishTime; - } - - function getPriceUnsafe(bytes32 id) - external - view - returns (PythPrice memory price); - -} - -contract Attacker { - - IERC20 usdc; - address zap; - - constructor(IERC20 _usdc, address _zap) { - usdc = _usdc; - zap = _zap; - } - - function sweep(IERC20 token) public { - token.transfer(msg.sender, token.balanceOf(address(this))); - } - - receive() external payable { - // could call back into zap to do another swap but that just pays more - // fees, no real profit - // could transfer usdc into zap for zap to be able to pay back the - // original caller but that is also just shuffling your own assets - // around - // cant call reenter into executeOperation because of access controls - } - -} - -contract EndToEndTest is Test, Arbitrum, Constants, OdosSwapData { - - Zap zap; - - ISpotMarket spotMarket; - IPerpsMarket perpsMarket; - - IERC20 usdc; - IERC20 susdc; - IERC20 usdx; - IERC20 weth; - - uint128 smallAccountIdNoOi = - 170_141_183_460_469_231_731_687_303_715_884_106_052; - address smallAccountNoOiOwner = 0xbd400F9a17DC18bc031DBF5ffCD2689F4BF650dD; - - uint128 smallAccountIdWithOi = - 170_141_183_460_469_231_731_687_303_715_884_106_146; - address smallAccountWithOiOwner = 0x46232CbDB0512Ca7B00B8271e285BF8447F1330b; - - uint128 largeAccountIdNoOi = - 170_141_183_460_469_231_731_687_303_715_884_105_759; - address largeAccountNoOiOwner = 0x626a7d9f7bBCaEB1Fa88E8128Bec8f2Dd48b2b4d; - - uint128 largeAccountIdWithOi = - 170_141_183_460_469_231_731_687_303_715_884_105_846; - address largeAccountWithOiOwner = 0x1C1e747A6BE850549E9655addf59FD9e7cC2D4dC; - - string RPC = vm.envString("ARBITRUM_RPC"); - mapping(string => uint256) FORK; - - modifier selectFork(uint256 fork) { - initilizeFork(fork); - _; - } - - function setUp() public { - FORK["0p0001_wrong"] = vm.createFork(RPC, blockNumber_0p0001_wrong); - FORK["0p001_wrong"] = vm.createFork(RPC, blockNumber_0p001_wrong); - FORK["0p01_wrong"] = vm.createFork(RPC, blockNumber_0p01_wrong); - FORK["0p1_wrong"] = vm.createFork(RPC, blockNumber_0p1_wrong); - FORK["1_wrong"] = vm.createFork(RPC, blockNumber_1_wrong); - FORK["10_wrong"] = vm.createFork(RPC, blockNumber_10_wrong); - FORK["100_wrong"] = vm.createFork(RPC, blockNumber_100_wrong); - - FORK["0p0001_zap"] = vm.createFork(RPC, blockNumber_0p0001_zap); - FORK["0p001_zap"] = vm.createFork(RPC, blockNumber_0p001_zap); - FORK["0p01_zap"] = vm.createFork(RPC, blockNumber_0p01_zap); - FORK["0p1_zap"] = vm.createFork(RPC, blockNumber_0p1_zap); - FORK["1_zap"] = vm.createFork(RPC, blockNumber_1_zap); - FORK["10_zap"] = vm.createFork(RPC, blockNumber_10_zap); - FORK["100_zap"] = vm.createFork(RPC, blockNumber_100_zap); - - FORK["1000_attacker"] = vm.createFork(RPC, blockNumber_1000_attacker); - } - - function initilizeFork(uint256 fork) public { - vm.selectFork(fork); - - spotMarket = ISpotMarket(ARBITRUM_SPOT_MARKET); - perpsMarket = IPerpsMarket(ARBITRUM_PERPS_MARKET); - - usdc = IERC20(ARBITRUM_USDC); - usdx = IERC20(ARBITRUM_USDX); - weth = IERC20(ARBITRUM_WETH); - - uint128 synthMarketId = ARBITRUM_SUSDC_SPOT_MARKET_ID; - - susdc = IERC20(spotMarket.getSynth(synthMarketId)); - - // create Zap contract to use actual sUSDC synth - zap = new Zap({ - _usdc: address(usdc), - _usdx: address(usdx), - _spotMarket: address(spotMarket), - _perpsMarket: address(perpsMarket), - _referrer: ARBITRUM_REFERRER, - _susdcSpotId: synthMarketId, - _aave: ARBITRUM_AAVE_POOL, - _router: ARBITRUM_ROUTER - }); - - IPyth pyth = IPyth(0xd74CdD8Eef0E97a5a7678F907991316f88E7965A); - - vm.mockCall( - address(pyth), - abi.encodeWithSignature( - "getPriceUnsafe(bytes32)", - 0xeaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a - ), - abi.encode( - 99_990_737, - 105_741, - 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_928, - block.timestamp - ) - ); - vm.mockCall( - address(pyth), - abi.encodeWithSignature( - "getPriceUnsafe(bytes32)", - 0x6ec879b1e9963de5ee97e9c8710b742d6228252a5e2ca12d4ae81d7fe5ee8c5d - ), - abi.encode(99_874_029, 139_807, int32(-8), block.timestamp) - ); - vm.mockCall( - address(pyth), - abi.encodeWithSignature( - "getPriceUnsafe(bytes32)", - 0xff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace - ), - abi.encode(314_393_291_700, 176_780_592, int32(-8), block.timestamp) - ); - vm.mockCall( - address(pyth), - abi.encodeWithSignature( - "getPriceUnsafe(bytes32)", - 0xd69731a2e74ac1ce884fc3890f7ee324b6deb66147055249568869ed700882e4 - ), - abi.encode(191_914, 287, int32(-10), block.timestamp) - ); - vm.mockCall( - address(pyth), - abi.encodeWithSignature( - "getPriceUnsafe(bytes32)", - 0xe62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43 - ), - abi.encode( - 9_798_709_797_025, 5_649_852_176, int32(-8), block.timestamp - ) - ); - } - - function _spin(address eoa, IERC20 token, uint256 amount) internal { - vm.assume(amount > 0); - deal(address(token), eoa, amount); - } - - // this test fails because unspent input asses it not refunded - function testOdosSwapSmall_Success() - public - selectFork(FORK["0p0001_zap"]) - { - address user = vm.addr(1); - uint256 amount = 1e18; - _spin(user, weth, amount); - - uint256 wethBefore = weth.balanceOf(address(user)); - uint256 usdcBefore = usdc.balanceOf(address(user)); - - vm.startPrank(user); - weth.approve(address(zap), amount); - zap.swapFrom(address(weth), swapData_0p0001_zap, amount, user); - vm.stopPrank(); - - assertEq(weth.balanceOf(address(user)), wethBefore - 0.0001 ether); - assertGt( - usdc.balanceOf(address(user)), - usdcBefore + ((1000 - 35) * outAmount_0p0001_zap / 1000) - ); - - assertEq(weth.balanceOf(address(zap)), 0); - assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); - } - - function testOdosSwapMedium_Success() public selectFork(FORK["1_zap"]) { - address user = vm.addr(1); - uint256 amount = 1e18; - _spin(user, weth, amount); - - uint256 wethBefore = weth.balanceOf(address(user)); - uint256 usdcBefore = usdc.balanceOf(address(user)); - - vm.startPrank(user); - weth.approve(address(zap), amount); - zap.swapFrom(address(weth), swapData_1_zap, amount, user); - vm.stopPrank(); - - assertEq(weth.balanceOf(address(user)), wethBefore - 1 ether); - assertGt( - usdc.balanceOf(address(user)), - usdcBefore + ((1000 - 35) * outAmount_1_zap / 1000) - ); - - assertEq(weth.balanceOf(address(zap)), 0); - assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); - } - - function testOdosSwapLarge_Success() public selectFork(FORK["10_zap"]) { - address user = vm.addr(1); - uint256 amount = 120e18; - _spin(user, weth, amount); - - uint256 wethBefore = weth.balanceOf(address(user)); - uint256 usdcBefore = usdc.balanceOf(address(user)); - - vm.startPrank(user); - weth.approve(address(zap), 100 ether); - zap.swapFrom(address(weth), swapData_10_zap, 10 ether, user); - vm.stopPrank(); - - assertEq(weth.balanceOf(address(user)), wethBefore - 10 ether); - assertGt( - usdc.balanceOf(address(user)), - usdcBefore + ((1000 - 35) * outAmount_10_zap / 1000) - ); - - assertEq(weth.balanceOf(address(zap)), 0); - assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); - } - - // this test fails because unspent input asset is not refunded - function testOdosSwapRepeat_Success() public selectFork(FORK["1_zap"]) { - // odos swap data can be repeated! - address user = vm.addr(1); - uint256 amount = 1e18; - _spin(user, weth, amount * 2); - - uint256 wethBefore = weth.balanceOf(address(user)); - uint256 usdcBefore = usdc.balanceOf(address(user)); - - vm.startPrank(user); - weth.approve(address(zap), amount); - zap.swapFrom(address(weth), swapData_1_zap, amount, user); - vm.stopPrank(); - - assertEq(weth.balanceOf(address(user)), wethBefore - 1 ether); - assertGe( - usdc.balanceOf(address(user)), - usdcBefore + ((1000 - 10) * outAmount_1_zap / 1000) - ); - - assertEq(weth.balanceOf(address(zap)), 0); - assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); - - vm.startPrank(user); - weth.approve(address(zap), amount); - zap.swapFrom(address(weth), swapData_1_zap, amount, user); - vm.stopPrank(); - - assertEq(weth.balanceOf(address(user)), wethBefore - 2 ether); - assertGe( - usdc.balanceOf(address(user)), - usdcBefore + 2 * ((1000 - 10) * outAmount_1_zap / 1000) - ); - - assertEq(weth.balanceOf(address(zap)), 0); - assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); - } - - function testOdosSwapSendToWrongAddress_Fail() - public - selectFork(FORK["1_wrong"]) - { - // failing because slippage exceeded - address user = vm.addr(1); - uint256 amount = 1e18; - _spin(user, weth, amount); - - uint256 wethBefore = weth.balanceOf(address(user)); - uint256 usdcBefore = usdc.balanceOf(address(user)); - - vm.startPrank(user); - weth.approve(address(zap), amount); - - vm.expectRevert(bytes("ERC20: transfer amount exceeds balance")); - zap.swapFrom(address(weth), swapData_1_wrong, amount, user); - vm.stopPrank(); - - assertEq(weth.balanceOf(address(user)), wethBefore); - assertEq(usdc.balanceOf(address(user)), usdcBefore); - - assertEq(weth.balanceOf(address(zap)), 0); - assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); - } - - function testOdosSwapSendToContract_Reentrancy_Success() - public - selectFork(FORK["10_attacker"]) - { - Attacker attackerContract = new Attacker(usdc, address(zap)); - uint256 amountUsdc = 1 ether; // non-realistic amount of USDC, but it is - // more to prove that the reentrancy is possible but not feasible or - // exploitable - address attacker = vm.addr(1234); - - _spin(attacker, usdc, amountUsdc); - - uint256 usdcBalBefore = usdc.balanceOf(attacker); - uint256 ethBalBefore = address(attackerContract).balance; - assertEq(ethBalBefore, 0); - assertEq(usdcBalBefore, amountUsdc); - - vm.startPrank(attacker); - usdc.approve(address(zap), amountUsdc); - zap.swapFrom(address(usdc), swapData_10_attacker, amountUsdc, attacker); - vm.stopPrank(); - - uint256 ethBalAfter = address(attackerContract).balance; - uint256 usdcBalAfter = usdc.balanceOf(attacker); - - assertGe( - ethBalAfter, - ethBalBefore + (1000 - 10) * outAmount_10_attacker / 1000 - ); - - uint256 unrefundedUsdcZap = usdc.balanceOf(address(zap)); - assertEq(unrefundedUsdcZap, 0); - // the final amounts are less than or equal to the amount provided - // initially, ie no profit - assertEq(usdcBalBefore, usdcBalAfter + inAmount_10_attacker); - } - - function testUnwindSmallDebtNoOI_Overpay_AccountOwner_Success() - public - selectFork(FORK["0p01_zap"]) - { - uint128 accountId = smallAccountIdNoOi; - address accountOwner = smallAccountNoOiOwner; - - uint256 tcvBefore = perpsMarket.totalCollateralValue(accountId); - uint256 debt = perpsMarket.debt(accountId); - uint256 collateralAmount = perpsMarket.getCollateralAmount(accountId, 4); - uint256 wethBefore = weth.balanceOf(address(this)); - uint256 usdcBefore = usdc.balanceOf(address(this)); - - assertGt(tcvBefore, 0); - assertGt(debt, 0); - assertEq(perpsMarket.totalAccountOpenInterest(accountId), 0); - - vm.startPrank(accountOwner); - perpsMarket.grantPermission( - accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) - ); - - zap.unwind( - accountId, - 4, // sETH collateral ID - collateralAmount, - address(weth), - swapData_0p01_zap, - 0, - 0, - 0.01 ether, - address(this) - ); - vm.stopPrank(); - - assertEq(perpsMarket.debt(accountId), 0); - assertEq(perpsMarket.totalCollateralValue(accountId), 0); - assertEq(perpsMarket.totalAccountOpenInterest(accountId), 0); - assertFalse( - perpsMarket.hasPermission( - accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) - ) - ); - - assertEq( - weth.balanceOf(address(this)), - wethBefore + collateralAmount - 0.01 ether - ); - assertGt( - usdc.balanceOf(address(this)), - usdcBefore + ((1000 - 35) * outAmount_0p01_zap / 1000) - - (debt / 1e12) - ); - - assertEq(weth.balanceOf(address(zap)), 0); - assertEq(usdc.balanceOf(address(zap)), 0); - assertLt(usdx.balanceOf(address(zap)), 1 ether); - } - - function testUnwindSmallDebtWithOI_OverPay_AccountOwner_Success() - public - selectFork(FORK["0p01_zap"]) - { - uint128 accountId = smallAccountIdWithOi; - address accountOwner = smallAccountWithOiOwner; - - uint256 tcvBefore = perpsMarket.totalCollateralValue(accountId); - uint256 debt = perpsMarket.debt(accountId); - uint256 collateralAmount = perpsMarket.getCollateralAmount(accountId, 4); - uint256 wethBefore = weth.balanceOf(address(this)); - uint256 usdcBefore = usdc.balanceOf(address(this)); - - assertGt(tcvBefore, 0); - assertGt(debt, 0); - assertGt(perpsMarket.totalAccountOpenInterest(accountId), 0); - - vm.startPrank(accountOwner); - perpsMarket.grantPermission( - accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) - ); - - zap.unwind( - accountId, - 4, // sETH collateral ID - 0.01 ether, - address(weth), - swapData_0p01_zap, - 0, - 0, - 0.01 ether, - address(this) - ); - vm.stopPrank(); - - assertEq(perpsMarket.debt(accountId), 0); - assertEq( - perpsMarket.getCollateralAmount(accountId, 4), - collateralAmount - 0.01 ether - ); - assertGt( - perpsMarket.totalCollateralValue(accountId), - tcvBefore - outValue_0p01_zap - ); // this check is weak because the oracle price on this block is diff - // from the odos api price - assertGt(perpsMarket.totalAccountOpenInterest(accountId), 0); - assertFalse( - perpsMarket.hasPermission( - accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) - ) - ); - - assertEq(weth.balanceOf(address(this)), wethBefore); - assertGt( - usdc.balanceOf(address(this)), - usdcBefore + ((1000 - 35) * outAmount_0p01_zap / 1000) - - (debt / 1e12) - ); - - assertEq(weth.balanceOf(address(zap)), 0); - assertEq(usdc.balanceOf(address(zap)), 0); - assertLt(usdx.balanceOf(address(zap)), 1 ether); - } - - function testUnwindSmallDebtNoOI_Underpay_AccountOwner_Fail() - public - selectFork(FORK["0p001_zap"]) - { - uint128 accountId = smallAccountIdNoOi; - address accountOwner = smallAccountNoOiOwner; - - uint256 tcvBefore = perpsMarket.totalCollateralValue(accountId); - uint256 debt = perpsMarket.debt(accountId); - uint256 collateralAmount = perpsMarket.getCollateralAmount(accountId, 4); - uint256 wethBefore = weth.balanceOf(address(this)); - uint256 usdcBefore = usdc.balanceOf(address(this)); - - assertGt(tcvBefore, 0); - assertGt(debt, 0); - assertEq(perpsMarket.totalAccountOpenInterest(accountId), 0); - - vm.startPrank(accountOwner); - perpsMarket.grantPermission( - accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) - ); - - vm.expectRevert(bytes("ERC20: transfer amount exceeds balance")); - zap.unwind( - accountId, - 4, // sETH collateral ID - collateralAmount, - address(weth), - swapData_0p001_zap, - 0, - 0, - 0.001 ether, - address(this) - ); - vm.stopPrank(); - - assertEq(perpsMarket.debt(accountId), debt); - assertEq(perpsMarket.totalCollateralValue(accountId), tcvBefore); - assertEq(perpsMarket.totalAccountOpenInterest(accountId), 0); - assertTrue( - perpsMarket.hasPermission( - accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) - ) - ); - - assertEq(weth.balanceOf(address(this)), wethBefore); - assertEq(usdc.balanceOf(address(this)), usdcBefore); - - assertEq(weth.balanceOf(address(zap)), 0); - assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); - } - - function testUnwindSmallDebtNoOI_Overpay_AccountOwner_OdosToWrongAddress_Fail( - ) - public - selectFork(FORK["0p01_wrong"]) - { - uint128 accountId = smallAccountIdNoOi; - address accountOwner = smallAccountNoOiOwner; - - uint256 tcvBefore = perpsMarket.totalCollateralValue(accountId); - uint256 debt = perpsMarket.debt(accountId); - uint256 collateralAmount = perpsMarket.getCollateralAmount(accountId, 4); - uint256 wethBefore = weth.balanceOf(address(this)); - uint256 usdcBefore = usdc.balanceOf(address(this)); - - assertGt(tcvBefore, 0); - assertGt(debt, 0); - assertEq(perpsMarket.totalAccountOpenInterest(accountId), 0); - - vm.startPrank(accountOwner); - perpsMarket.grantPermission( - accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) - ); - - vm.expectRevert(bytes("ERC20: transfer amount exceeds balance")); - zap.unwind( - accountId, - 4, // sETH collateral ID - collateralAmount, - address(weth), - swapData_0p01_wrong, - 0, - 0, - 0.01 ether, - address(this) - ); - vm.stopPrank(); - - assertEq(perpsMarket.debt(accountId), debt); - assertEq(perpsMarket.totalCollateralValue(accountId), tcvBefore); - assertEq(perpsMarket.totalAccountOpenInterest(accountId), 0); - assertTrue( - perpsMarket.hasPermission( - accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) - ) - ); - - assertEq(weth.balanceOf(address(this)), wethBefore); - assertEq(usdc.balanceOf(address(this)), usdcBefore); - - assertEq(weth.balanceOf(address(zap)), 0); - assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); - } - - error NotPermitted(); - - function testUnwindSmallDebtNoOI_Overpay_NotAccountOwner_Fail() - public - selectFork(FORK["0p01_zap"]) - { - uint128 accountId = smallAccountIdNoOi; - address accountOwner = smallAccountNoOiOwner; - - uint256 tcvBefore = perpsMarket.totalCollateralValue(accountId); - uint256 debt = perpsMarket.debt(accountId); - uint256 collateralAmount = perpsMarket.getCollateralAmount(accountId, 4); - uint256 wethBefore = weth.balanceOf(address(this)); - uint256 usdcBefore = usdc.balanceOf(address(this)); - - assertGt(tcvBefore, 0); - assertGt(debt, 0); - assertEq(perpsMarket.totalAccountOpenInterest(accountId), 0); - - vm.startPrank(accountOwner); - perpsMarket.grantPermission( - accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) - ); - vm.stopPrank(); - - vm.expectRevert(abi.encodeWithSelector(NotPermitted.selector)); - zap.unwind( - accountId, - 4, - collateralAmount, - address(weth), - swapData_0p001_zap, - 0, - 0, - 0.001 ether, - address(this) - ); - - assertEq(perpsMarket.debt(accountId), debt); - assertEq(perpsMarket.totalCollateralValue(accountId), tcvBefore); - assertEq(perpsMarket.totalAccountOpenInterest(accountId), 0); - assertTrue( - perpsMarket.hasPermission( - accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) - ) - ); - - assertEq(weth.balanceOf(address(this)), wethBefore); - assertEq(usdc.balanceOf(address(this)), usdcBefore); - - assertEq(weth.balanceOf(address(zap)), 0); - assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); - } - - function testUnwindSmallDebtNoOI_ZapNotPermitted_Fail() - public - selectFork(FORK["0p01_zap"]) - { - uint128 accountId = smallAccountIdNoOi; - address accountOwner = smallAccountNoOiOwner; - - uint256 tcvBefore = perpsMarket.totalCollateralValue(accountId); - uint256 debt = perpsMarket.debt(accountId); - uint256 collateralAmount = perpsMarket.getCollateralAmount(accountId, 4); - uint256 wethBefore = weth.balanceOf(address(this)); - uint256 usdcBefore = usdc.balanceOf(address(this)); - - assertGt(tcvBefore, 0); - assertGt(debt, 0); - assertEq(perpsMarket.totalAccountOpenInterest(accountId), 0); - - vm.startPrank(accountOwner); - vm.expectRevert( - abi.encodeWithSelector( - IPerpsMarket.PermissionDenied.selector, - 170_141_183_460_469_231_731_687_303_715_884_106_052, - _PERPS_MODIFY_COLLATERAL_PERMISSION, - 0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f - ) - ); - zap.unwind( - accountId, - 4, - collateralAmount, - address(weth), - swapData_0p001_zap, - 0, - 0, - 0.001 ether, - address(this) - ); - vm.stopPrank(); - - assertEq(perpsMarket.debt(accountId), debt); - assertEq(perpsMarket.totalCollateralValue(accountId), tcvBefore); - assertEq(perpsMarket.totalAccountOpenInterest(accountId), 0); - assertFalse( - perpsMarket.hasPermission( - accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) - ) - ); - - assertEq(weth.balanceOf(address(this)), wethBefore); - assertEq(usdc.balanceOf(address(this)), usdcBefore); - - assertEq(weth.balanceOf(address(zap)), 0); - assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); - } - - error OnlyAave(address); - - function testUnwindFailDirectCallback() - public - selectFork(FORK["0p01_zap"]) - { - vm.expectRevert( - abi.encodeWithSelector(OnlyAave.selector, address(this)) - ); - zap.executeOperation(address(0), 0, 0, address(0), ""); - } - - error ReentrancyDetected(uint8, uint8); - - function testUnwindFailDirectCallbackInvalidOrigin() - public - selectFork(FORK["0p01_zap"]) - { - vm.startPrank(ARBITRUM_AAVE_POOL); - vm.expectRevert( - abi.encodeWithSelector(ReentrancyDetected.selector, 0, 1) - ); - zap.executeOperation(address(0), 0, 0, address(0), ""); - vm.stopPrank(); - } - - function testUnwindLargeDebtNoOI_Overpay_AccountOwner_Success() - public - selectFork(FORK["10_zap"]) - { - uint128 accountId = largeAccountIdNoOi; - address accountOwner = largeAccountNoOiOwner; - - uint256 tcvBefore = perpsMarket.totalCollateralValue(accountId); - uint256 debt = perpsMarket.debt(accountId); - uint256 collateralAmount = perpsMarket.getCollateralAmount(accountId, 4); - uint256 wethBefore = weth.balanceOf(address(this)); - uint256 usdcBefore = usdc.balanceOf(address(this)); - - assertGt(tcvBefore, 0); - assertGt(debt, 0); - assertEq(perpsMarket.totalAccountOpenInterest(accountId), 0); - - vm.startPrank(accountOwner); - perpsMarket.grantPermission( - accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) - ); - - zap.unwind( - accountId, - 4, // sETH collateral ID - collateralAmount, - address(weth), - swapData_10_zap, - 0, - 0, - 10 ether, - address(this) - ); - vm.stopPrank(); - - assertEq(perpsMarket.debt(accountId), 0); - assertEq(perpsMarket.totalCollateralValue(accountId), 0); - assertEq(perpsMarket.totalAccountOpenInterest(accountId), 0); - assertFalse( - perpsMarket.hasPermission( - accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) - ) - ); - - assertEq( - weth.balanceOf(address(this)), - wethBefore + collateralAmount - 10 ether - ); - assertGt( - usdc.balanceOf(address(this)), - usdcBefore + ((1000 - 2) * outAmount_10_zap / 1000) - (debt / 1e12) - ); - - assertEq(weth.balanceOf(address(zap)), 0); - assertEq(usdc.balanceOf(address(zap)), 0); - assertLt(usdx.balanceOf(address(zap)), 1 ether); - } - - function testUnwindLargeDebtWithOI_OverPay_AccountOwner_Success() - public - selectFork(FORK["10_zap"]) - { - uint128 accountId = largeAccountIdWithOi; - address accountOwner = largeAccountWithOiOwner; - - uint256 tcvBefore = perpsMarket.totalCollateralValue(accountId); - uint256 debt = perpsMarket.debt(accountId); - uint256 collateralAmount = perpsMarket.getCollateralAmount(accountId, 4); - uint256 wethBefore = weth.balanceOf(address(this)); - uint256 usdcBefore = usdc.balanceOf(address(this)); - - assertGt(tcvBefore, 0); - assertGt(debt, 0); - assertGt(perpsMarket.totalAccountOpenInterest(accountId), 0); - - vm.startPrank(accountOwner); - perpsMarket.grantPermission( - accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) - ); - - zap.unwind( - accountId, - 4, // sETH collateral ID - 10 ether, - address(weth), - swapData_10_zap, - 0, - 0, - 10 ether, - address(this) - ); - vm.stopPrank(); - - assertEq(perpsMarket.debt(accountId), 0); - assertEq( - perpsMarket.getCollateralAmount(accountId, 4), - collateralAmount - 10 ether - ); - assertGt( - perpsMarket.totalCollateralValue(accountId), - tcvBefore - outValue_10_zap - ); // this check is weak because the oracle price on this block is diff - // from the odos api price - assertGt(perpsMarket.totalAccountOpenInterest(accountId), 0); - assertFalse( - perpsMarket.hasPermission( - accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) - ) - ); - - assertEq(weth.balanceOf(address(this)), wethBefore); - assertGt( - usdc.balanceOf(address(this)), - usdcBefore + ((1000 - 1) * outAmount_10_zap / 1000) - (debt / 1e12) - ); - - assertEq(weth.balanceOf(address(zap)), 0); - assertEq(usdc.balanceOf(address(zap)), 0); - assertLt(usdx.balanceOf(address(zap)), 1 ether); - } - - function testBurnSmallDebtNoOI_Exact_AccountOwner_Success() - public - selectFork(FORK["1_zap"]) - { - uint128 accountId = smallAccountIdNoOi; - address accountOwner = smallAccountNoOiOwner; - - // check account debt - uint256 debt = perpsMarket.debt(accountId); - - uint256 amount = debt; - - _spin(accountOwner, usdx, amount); - uint256 balanceBefore = usdx.balanceOf(accountOwner); - - vm.startPrank(accountOwner); - usdx.approve(address(zap), amount); - zap.burn(amount, accountId); - vm.stopPrank(); - - assertEq(perpsMarket.debt(accountId), 0); - assertEq(usdx.balanceOf(accountOwner), balanceBefore - debt); - - assertEq(weth.balanceOf(address(zap)), 0); - assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); - } - - function testBurnSmallDebtNoOI_Exact_NotAccountOwner_Success() - public - selectFork(FORK["1_zap"]) - { - uint128 accountId = smallAccountIdNoOi; - address user = vm.addr(1234); - - // check account debt - uint256 debt = perpsMarket.debt(accountId); - - uint256 amount = debt; - - _spin(user, usdx, amount); - uint256 balanceBefore = usdx.balanceOf(user); - - vm.startPrank(user); - usdx.approve(address(zap), amount); - zap.burn(amount, accountId); - vm.stopPrank(); - - assertEq(perpsMarket.debt(accountId), 0); - assertEq(usdx.balanceOf(user), balanceBefore - debt); - - assertEq(weth.balanceOf(address(zap)), 0); - assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); - } - - function testBurnSmallDebtNoOI_Overpay_AccountOwner_Success() - public - selectFork(FORK["1_zap"]) - { - uint128 accountId = smallAccountIdNoOi; - address accountOwner = smallAccountNoOiOwner; - - // check account debt - uint256 debt = perpsMarket.debt(accountId); - - uint256 amount = 123_456_789 + debt; - - _spin(accountOwner, usdx, amount); - uint256 balanceBefore = usdx.balanceOf(accountOwner); - - vm.startPrank(accountOwner); - usdx.approve(address(zap), amount); - zap.burn(amount, accountId); - vm.stopPrank(); - - assertEq(perpsMarket.debt(accountId), 0); - assertEq(usdx.balanceOf(accountOwner), balanceBefore - debt); - assertEq(usdx.balanceOf(accountOwner), 123_456_789); - - assertEq(weth.balanceOf(address(zap)), 0); - assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); - } - - function testBurnSmallDebtNoOI_Overpay_NotAccountOwner_Success() - public - selectFork(FORK["1_zap"]) - { - uint128 accountId = smallAccountIdNoOi; - address user = vm.addr(1234); - - // check account debt - uint256 debt = perpsMarket.debt(accountId); +/// @custom:disabled no stata on arbitrum + +// // SPDX-License-Identifier: MIT +// pragma solidity 0.8.27; + +// import {Arbitrum} from "../script/utils/Parameters.sol"; +// import {IERC20, Zap} from "../src/Zap.sol"; +// import {Flush} from "../src/utils/Flush.sol"; +// import "./interfaces/ISynthetix.sol"; + +// import {Bootstrap} from "./utils/Bootstrap.sol"; +// import {Constants} from "./utils/Constants.sol"; +// import {OdosSwapData} from "./utils/OdosSwapData.sol"; +// import "forge-std/Test.sol"; + +// interface IPyth { + +// struct PythPrice { +// // Price +// int64 price; +// // Confidence interval around the price +// uint64 conf; +// // Price exponent +// int32 expo; +// // Unix timestamp describing when the price was published +// uint256 publishTime; +// } + +// function getPriceUnsafe(bytes32 id) +// external +// view +// returns (PythPrice memory price); + +// } + +// contract Attacker { + +// IERC20 usdc; +// address zap; + +// constructor(IERC20 _usdc, address _zap) { +// usdc = _usdc; +// zap = _zap; +// } + +// function sweep(IERC20 token) public { +// token.transfer(msg.sender, token.balanceOf(address(this))); +// } + +// receive() external payable { +// // could call back into zap to do another swap but that just pays more +// // fees, no real profit +// // could transfer usdc into zap for zap to be able to pay back the +// // original caller but that is also just shuffling your own assets +// // around +// // cant call reenter into executeOperation because of access controls +// } + +// } + +// contract EndToEndTest is Test, Arbitrum, Constants, OdosSwapData { + +// Zap zap; + +// ISpotMarket spotMarket; +// IPerpsMarket perpsMarket; + +// IERC20 usdc; +// IERC20 susdc; +// IERC20 usdx; +// IERC20 weth; + +// uint128 smallAccountIdNoOi = +// 170_141_183_460_469_231_731_687_303_715_884_106_052; +// address smallAccountNoOiOwner = 0xbd400F9a17DC18bc031DBF5ffCD2689F4BF650dD; + +// uint128 smallAccountIdWithOi = +// 170_141_183_460_469_231_731_687_303_715_884_106_146; +// address smallAccountWithOiOwner = 0x46232CbDB0512Ca7B00B8271e285BF8447F1330b; + +// uint128 largeAccountIdNoOi = +// 170_141_183_460_469_231_731_687_303_715_884_105_759; +// address largeAccountNoOiOwner = 0x626a7d9f7bBCaEB1Fa88E8128Bec8f2Dd48b2b4d; + +// uint128 largeAccountIdWithOi = +// 170_141_183_460_469_231_731_687_303_715_884_105_846; +// address largeAccountWithOiOwner = 0x1C1e747A6BE850549E9655addf59FD9e7cC2D4dC; + +// string RPC = vm.envString("ARBITRUM_RPC"); +// mapping(string => uint256) FORK; + +// modifier selectFork(uint256 fork) { +// initilizeFork(fork); +// _; +// } + +// function setUp() public { +// FORK["0p0001_wrong"] = vm.createFork(RPC, blockNumber_0p0001_wrong); +// FORK["0p001_wrong"] = vm.createFork(RPC, blockNumber_0p001_wrong); +// FORK["0p01_wrong"] = vm.createFork(RPC, blockNumber_0p01_wrong); +// FORK["0p1_wrong"] = vm.createFork(RPC, blockNumber_0p1_wrong); +// FORK["1_wrong"] = vm.createFork(RPC, blockNumber_1_wrong); +// FORK["10_wrong"] = vm.createFork(RPC, blockNumber_10_wrong); +// FORK["100_wrong"] = vm.createFork(RPC, blockNumber_100_wrong); + +// FORK["0p0001_zap"] = vm.createFork(RPC, blockNumber_0p0001_zap); +// FORK["0p001_zap"] = vm.createFork(RPC, blockNumber_0p001_zap); +// FORK["0p01_zap"] = vm.createFork(RPC, blockNumber_0p01_zap); +// FORK["0p1_zap"] = vm.createFork(RPC, blockNumber_0p1_zap); +// FORK["1_zap"] = vm.createFork(RPC, blockNumber_1_zap); +// FORK["10_zap"] = vm.createFork(RPC, blockNumber_10_zap); +// FORK["100_zap"] = vm.createFork(RPC, blockNumber_100_zap); + +// FORK["1000_attacker"] = vm.createFork(RPC, blockNumber_1000_attacker); +// } + +// function initilizeFork(uint256 fork) public { +// vm.selectFork(fork); + +// spotMarket = ISpotMarket(ARBITRUM_SPOT_MARKET); +// perpsMarket = IPerpsMarket(ARBITRUM_PERPS_MARKET); + +// usdc = IERC20(ARBITRUM_USDC); +// usdx = IERC20(ARBITRUM_USDX); +// weth = IERC20(ARBITRUM_WETH); + +// uint128 synthMarketId = ARBITRUM_SUSDC_SPOT_MARKET_ID; + +// susdc = IERC20(spotMarket.getSynth(synthMarketId)); + +// // create Zap contract to use actual sUSDC synth +// zap = new Zap({ +// _usdc: address(usdc), +// _usdx: address(usdx), +// _sstata: address(0), // no stata on arbitrum +// _spotMarket: address(spotMarket), +// _perpsMarket: address(perpsMarket), +// _referrer: ARBITRUM_REFERRER, +// _susdcSpotId: synthMarketId, +// _sstataSpotId: 0, // no stata on arbitrum +// _aave: ARBITRUM_AAVE_POOL, +// _stata: address(0), // no stata on arbitrum +// _router: ARBITRUM_ROUTER +// }); + +// IPyth pyth = IPyth(0xd74CdD8Eef0E97a5a7678F907991316f88E7965A); + +// vm.mockCall( +// address(pyth), +// abi.encodeWithSignature( +// "getPriceUnsafe(bytes32)", +// 0xeaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a +// ), +// abi.encode( +// 99_990_737, +// 105_741, +// 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_928, +// block.timestamp +// ) +// ); +// vm.mockCall( +// address(pyth), +// abi.encodeWithSignature( +// "getPriceUnsafe(bytes32)", +// 0x6ec879b1e9963de5ee97e9c8710b742d6228252a5e2ca12d4ae81d7fe5ee8c5d +// ), +// abi.encode(99_874_029, 139_807, int32(-8), block.timestamp) +// ); +// vm.mockCall( +// address(pyth), +// abi.encodeWithSignature( +// "getPriceUnsafe(bytes32)", +// 0xff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace +// ), +// abi.encode(314_393_291_700, 176_780_592, int32(-8), block.timestamp) +// ); +// vm.mockCall( +// address(pyth), +// abi.encodeWithSignature( +// "getPriceUnsafe(bytes32)", +// 0xd69731a2e74ac1ce884fc3890f7ee324b6deb66147055249568869ed700882e4 +// ), +// abi.encode(191_914, 287, int32(-10), block.timestamp) +// ); +// vm.mockCall( +// address(pyth), +// abi.encodeWithSignature( +// "getPriceUnsafe(bytes32)", +// 0xe62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43 +// ), +// abi.encode( +// 9_798_709_797_025, 5_649_852_176, int32(-8), block.timestamp +// ) +// ); +// } + +// function _spin(address eoa, IERC20 token, uint256 amount) internal { +// vm.assume(amount > 0); +// deal(address(token), eoa, amount); +// } + +// // this test fails because unspent input asses it not refunded +// function testOdosSwapSmall_Success() +// public +// selectFork(FORK["0p0001_zap"]) +// { +// address user = vm.addr(1); +// uint256 amount = 1e18; +// _spin(user, weth, amount); + +// uint256 wethBefore = weth.balanceOf(address(user)); +// uint256 usdcBefore = usdc.balanceOf(address(user)); + +// vm.startPrank(user); +// weth.approve(address(zap), amount); +// zap.swapFrom(address(weth), swapData_0p0001_zap, amount, user); +// vm.stopPrank(); + +// assertEq(weth.balanceOf(address(user)), wethBefore - 0.0001 ether); +// assertGt( +// usdc.balanceOf(address(user)), +// usdcBefore + ((1000 - 35) * outAmount_0p0001_zap / 1000) +// ); + +// assertEq(weth.balanceOf(address(zap)), 0); +// assertEq(usdc.balanceOf(address(zap)), 0); +// assertEq(usdx.balanceOf(address(zap)), 0); +// } + +// function testOdosSwapMedium_Success() public selectFork(FORK["1_zap"]) { +// address user = vm.addr(1); +// uint256 amount = 1e18; +// _spin(user, weth, amount); + +// uint256 wethBefore = weth.balanceOf(address(user)); +// uint256 usdcBefore = usdc.balanceOf(address(user)); + +// vm.startPrank(user); +// weth.approve(address(zap), amount); +// zap.swapFrom(address(weth), swapData_1_zap, amount, user); +// vm.stopPrank(); + +// assertEq(weth.balanceOf(address(user)), wethBefore - 1 ether); +// assertGt( +// usdc.balanceOf(address(user)), +// usdcBefore + ((1000 - 35) * outAmount_1_zap / 1000) +// ); + +// assertEq(weth.balanceOf(address(zap)), 0); +// assertEq(usdc.balanceOf(address(zap)), 0); +// assertEq(usdx.balanceOf(address(zap)), 0); +// } + +// function testOdosSwapLarge_Success() public selectFork(FORK["10_zap"]) { +// address user = vm.addr(1); +// uint256 amount = 120e18; +// _spin(user, weth, amount); + +// uint256 wethBefore = weth.balanceOf(address(user)); +// uint256 usdcBefore = usdc.balanceOf(address(user)); + +// vm.startPrank(user); +// weth.approve(address(zap), 100 ether); +// zap.swapFrom(address(weth), swapData_10_zap, 10 ether, user); +// vm.stopPrank(); + +// assertEq(weth.balanceOf(address(user)), wethBefore - 10 ether); +// assertGt( +// usdc.balanceOf(address(user)), +// usdcBefore + ((1000 - 35) * outAmount_10_zap / 1000) +// ); + +// assertEq(weth.balanceOf(address(zap)), 0); +// assertEq(usdc.balanceOf(address(zap)), 0); +// assertEq(usdx.balanceOf(address(zap)), 0); +// } + +// // this test fails because unspent input asset is not refunded +// function testOdosSwapRepeat_Success() public selectFork(FORK["1_zap"]) { +// // odos swap data can be repeated! +// address user = vm.addr(1); +// uint256 amount = 1e18; +// _spin(user, weth, amount * 2); + +// uint256 wethBefore = weth.balanceOf(address(user)); +// uint256 usdcBefore = usdc.balanceOf(address(user)); + +// vm.startPrank(user); +// weth.approve(address(zap), amount); +// zap.swapFrom(address(weth), swapData_1_zap, amount, user); +// vm.stopPrank(); + +// assertEq(weth.balanceOf(address(user)), wethBefore - 1 ether); +// assertGe( +// usdc.balanceOf(address(user)), +// usdcBefore + ((1000 - 10) * outAmount_1_zap / 1000) +// ); + +// assertEq(weth.balanceOf(address(zap)), 0); +// assertEq(usdc.balanceOf(address(zap)), 0); +// assertEq(usdx.balanceOf(address(zap)), 0); + +// vm.startPrank(user); +// weth.approve(address(zap), amount); +// zap.swapFrom(address(weth), swapData_1_zap, amount, user); +// vm.stopPrank(); + +// assertEq(weth.balanceOf(address(user)), wethBefore - 2 ether); +// assertGe( +// usdc.balanceOf(address(user)), +// usdcBefore + 2 * ((1000 - 10) * outAmount_1_zap / 1000) +// ); + +// assertEq(weth.balanceOf(address(zap)), 0); +// assertEq(usdc.balanceOf(address(zap)), 0); +// assertEq(usdx.balanceOf(address(zap)), 0); +// } + +// function testOdosSwapSendToWrongAddress_Fail() +// public +// selectFork(FORK["1_wrong"]) +// { +// // failing because slippage exceeded +// address user = vm.addr(1); +// uint256 amount = 1e18; +// _spin(user, weth, amount); + +// uint256 wethBefore = weth.balanceOf(address(user)); +// uint256 usdcBefore = usdc.balanceOf(address(user)); + +// vm.startPrank(user); +// weth.approve(address(zap), amount); + +// vm.expectRevert(bytes("ERC20: transfer amount exceeds balance")); +// zap.swapFrom(address(weth), swapData_1_wrong, amount, user); +// vm.stopPrank(); + +// assertEq(weth.balanceOf(address(user)), wethBefore); +// assertEq(usdc.balanceOf(address(user)), usdcBefore); + +// assertEq(weth.balanceOf(address(zap)), 0); +// assertEq(usdc.balanceOf(address(zap)), 0); +// assertEq(usdx.balanceOf(address(zap)), 0); +// } + +// function testOdosSwapSendToContract_Reentrancy_Success() +// public +// selectFork(FORK["10_attacker"]) +// { +// Attacker attackerContract = new Attacker(usdc, address(zap)); +// uint256 amountUsdc = 1 ether; // non-realistic amount of USDC, but it is +// // more to prove that the reentrancy is possible but not feasible or +// // exploitable +// address attacker = vm.addr(1234); + +// _spin(attacker, usdc, amountUsdc); + +// uint256 usdcBalBefore = usdc.balanceOf(attacker); +// uint256 ethBalBefore = address(attackerContract).balance; +// assertEq(ethBalBefore, 0); +// assertEq(usdcBalBefore, amountUsdc); + +// vm.startPrank(attacker); +// usdc.approve(address(zap), amountUsdc); +// zap.swapFrom(address(usdc), swapData_10_attacker, amountUsdc, attacker); +// vm.stopPrank(); + +// uint256 ethBalAfter = address(attackerContract).balance; +// uint256 usdcBalAfter = usdc.balanceOf(attacker); + +// assertGe( +// ethBalAfter, +// ethBalBefore + (1000 - 10) * outAmount_10_attacker / 1000 +// ); + +// uint256 unrefundedUsdcZap = usdc.balanceOf(address(zap)); +// assertEq(unrefundedUsdcZap, 0); +// // the final amounts are less than or equal to the amount provided +// // initially, ie no profit +// assertEq(usdcBalBefore, usdcBalAfter + inAmount_10_attacker); +// } + +// function testUnwindSmallDebtNoOI_Overpay_AccountOwner_Success() +// public +// selectFork(FORK["0p01_zap"]) +// { +// uint128 accountId = smallAccountIdNoOi; +// address accountOwner = smallAccountNoOiOwner; + +// uint256 tcvBefore = perpsMarket.totalCollateralValue(accountId); +// uint256 debt = perpsMarket.debt(accountId); +// uint256 collateralAmount = perpsMarket.getCollateralAmount(accountId, 4); +// uint256 wethBefore = weth.balanceOf(address(this)); +// uint256 usdcBefore = usdc.balanceOf(address(this)); + +// assertGt(tcvBefore, 0); +// assertGt(debt, 0); +// assertEq(perpsMarket.totalAccountOpenInterest(accountId), 0); + +// vm.startPrank(accountOwner); +// perpsMarket.grantPermission( +// accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) +// ); + +// zap.unwind( +// accountId, +// 4, // sETH collateral ID +// collateralAmount, +// address(weth), +// swapData_0p01_zap, +// 0, +// 0, +// 0.01 ether, +// address(this) +// ); +// vm.stopPrank(); + +// assertEq(perpsMarket.debt(accountId), 0); +// assertEq(perpsMarket.totalCollateralValue(accountId), 0); +// assertEq(perpsMarket.totalAccountOpenInterest(accountId), 0); +// assertFalse( +// perpsMarket.hasPermission( +// accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) +// ) +// ); + +// assertEq( +// weth.balanceOf(address(this)), +// wethBefore + collateralAmount - 0.01 ether +// ); +// assertGt( +// usdc.balanceOf(address(this)), +// usdcBefore + ((1000 - 35) * outAmount_0p01_zap / 1000) +// - (debt / 1e12) +// ); + +// assertEq(weth.balanceOf(address(zap)), 0); +// assertEq(usdc.balanceOf(address(zap)), 0); +// assertLt(usdx.balanceOf(address(zap)), 1 ether); +// } + +// function testUnwindSmallDebtWithOI_OverPay_AccountOwner_Success() +// public +// selectFork(FORK["0p01_zap"]) +// { +// uint128 accountId = smallAccountIdWithOi; +// address accountOwner = smallAccountWithOiOwner; + +// uint256 tcvBefore = perpsMarket.totalCollateralValue(accountId); +// uint256 debt = perpsMarket.debt(accountId); +// uint256 collateralAmount = perpsMarket.getCollateralAmount(accountId, 4); +// uint256 wethBefore = weth.balanceOf(address(this)); +// uint256 usdcBefore = usdc.balanceOf(address(this)); + +// assertGt(tcvBefore, 0); +// assertGt(debt, 0); +// assertGt(perpsMarket.totalAccountOpenInterest(accountId), 0); + +// vm.startPrank(accountOwner); +// perpsMarket.grantPermission( +// accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) +// ); + +// zap.unwind( +// accountId, +// 4, // sETH collateral ID +// 0.01 ether, +// address(weth), +// swapData_0p01_zap, +// 0, +// 0, +// 0.01 ether, +// address(this) +// ); +// vm.stopPrank(); + +// assertEq(perpsMarket.debt(accountId), 0); +// assertEq( +// perpsMarket.getCollateralAmount(accountId, 4), +// collateralAmount - 0.01 ether +// ); +// assertGt( +// perpsMarket.totalCollateralValue(accountId), +// tcvBefore - outValue_0p01_zap +// ); // this check is weak because the oracle price on this block is diff +// // from the odos api price +// assertGt(perpsMarket.totalAccountOpenInterest(accountId), 0); +// assertFalse( +// perpsMarket.hasPermission( +// accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) +// ) +// ); + +// assertEq(weth.balanceOf(address(this)), wethBefore); +// assertGt( +// usdc.balanceOf(address(this)), +// usdcBefore + ((1000 - 35) * outAmount_0p01_zap / 1000) +// - (debt / 1e12) +// ); + +// assertEq(weth.balanceOf(address(zap)), 0); +// assertEq(usdc.balanceOf(address(zap)), 0); +// assertLt(usdx.balanceOf(address(zap)), 1 ether); +// } + +// function testUnwindSmallDebtNoOI_Underpay_AccountOwner_Fail() +// public +// selectFork(FORK["0p001_zap"]) +// { +// uint128 accountId = smallAccountIdNoOi; +// address accountOwner = smallAccountNoOiOwner; + +// uint256 tcvBefore = perpsMarket.totalCollateralValue(accountId); +// uint256 debt = perpsMarket.debt(accountId); +// uint256 collateralAmount = perpsMarket.getCollateralAmount(accountId, 4); +// uint256 wethBefore = weth.balanceOf(address(this)); +// uint256 usdcBefore = usdc.balanceOf(address(this)); + +// assertGt(tcvBefore, 0); +// assertGt(debt, 0); +// assertEq(perpsMarket.totalAccountOpenInterest(accountId), 0); + +// vm.startPrank(accountOwner); +// perpsMarket.grantPermission( +// accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) +// ); + +// vm.expectRevert(bytes("ERC20: transfer amount exceeds balance")); +// zap.unwind( +// accountId, +// 4, // sETH collateral ID +// collateralAmount, +// address(weth), +// swapData_0p001_zap, +// 0, +// 0, +// 0.001 ether, +// address(this) +// ); +// vm.stopPrank(); + +// assertEq(perpsMarket.debt(accountId), debt); +// assertEq(perpsMarket.totalCollateralValue(accountId), tcvBefore); +// assertEq(perpsMarket.totalAccountOpenInterest(accountId), 0); +// assertTrue( +// perpsMarket.hasPermission( +// accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) +// ) +// ); + +// assertEq(weth.balanceOf(address(this)), wethBefore); +// assertEq(usdc.balanceOf(address(this)), usdcBefore); + +// assertEq(weth.balanceOf(address(zap)), 0); +// assertEq(usdc.balanceOf(address(zap)), 0); +// assertEq(usdx.balanceOf(address(zap)), 0); +// } + +// function testUnwindSmallDebtNoOI_Overpay_AccountOwner_OdosToWrongAddress_Fail( +// ) +// public +// selectFork(FORK["0p01_wrong"]) +// { +// uint128 accountId = smallAccountIdNoOi; +// address accountOwner = smallAccountNoOiOwner; + +// uint256 tcvBefore = perpsMarket.totalCollateralValue(accountId); +// uint256 debt = perpsMarket.debt(accountId); +// uint256 collateralAmount = perpsMarket.getCollateralAmount(accountId, 4); +// uint256 wethBefore = weth.balanceOf(address(this)); +// uint256 usdcBefore = usdc.balanceOf(address(this)); + +// assertGt(tcvBefore, 0); +// assertGt(debt, 0); +// assertEq(perpsMarket.totalAccountOpenInterest(accountId), 0); + +// vm.startPrank(accountOwner); +// perpsMarket.grantPermission( +// accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) +// ); + +// vm.expectRevert(bytes("ERC20: transfer amount exceeds balance")); +// zap.unwind( +// accountId, +// 4, // sETH collateral ID +// collateralAmount, +// address(weth), +// swapData_0p01_wrong, +// 0, +// 0, +// 0.01 ether, +// address(this) +// ); +// vm.stopPrank(); + +// assertEq(perpsMarket.debt(accountId), debt); +// assertEq(perpsMarket.totalCollateralValue(accountId), tcvBefore); +// assertEq(perpsMarket.totalAccountOpenInterest(accountId), 0); +// assertTrue( +// perpsMarket.hasPermission( +// accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) +// ) +// ); + +// assertEq(weth.balanceOf(address(this)), wethBefore); +// assertEq(usdc.balanceOf(address(this)), usdcBefore); + +// assertEq(weth.balanceOf(address(zap)), 0); +// assertEq(usdc.balanceOf(address(zap)), 0); +// assertEq(usdx.balanceOf(address(zap)), 0); +// } + +// error NotPermitted(); + +// function testUnwindSmallDebtNoOI_Overpay_NotAccountOwner_Fail() +// public +// selectFork(FORK["0p01_zap"]) +// { +// uint128 accountId = smallAccountIdNoOi; +// address accountOwner = smallAccountNoOiOwner; + +// uint256 tcvBefore = perpsMarket.totalCollateralValue(accountId); +// uint256 debt = perpsMarket.debt(accountId); +// uint256 collateralAmount = perpsMarket.getCollateralAmount(accountId, 4); +// uint256 wethBefore = weth.balanceOf(address(this)); +// uint256 usdcBefore = usdc.balanceOf(address(this)); + +// assertGt(tcvBefore, 0); +// assertGt(debt, 0); +// assertEq(perpsMarket.totalAccountOpenInterest(accountId), 0); + +// vm.startPrank(accountOwner); +// perpsMarket.grantPermission( +// accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) +// ); +// vm.stopPrank(); + +// vm.expectRevert(abi.encodeWithSelector(NotPermitted.selector)); +// zap.unwind( +// accountId, +// 4, +// collateralAmount, +// address(weth), +// swapData_0p001_zap, +// 0, +// 0, +// 0.001 ether, +// address(this) +// ); + +// assertEq(perpsMarket.debt(accountId), debt); +// assertEq(perpsMarket.totalCollateralValue(accountId), tcvBefore); +// assertEq(perpsMarket.totalAccountOpenInterest(accountId), 0); +// assertTrue( +// perpsMarket.hasPermission( +// accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) +// ) +// ); + +// assertEq(weth.balanceOf(address(this)), wethBefore); +// assertEq(usdc.balanceOf(address(this)), usdcBefore); + +// assertEq(weth.balanceOf(address(zap)), 0); +// assertEq(usdc.balanceOf(address(zap)), 0); +// assertEq(usdx.balanceOf(address(zap)), 0); +// } + +// function testUnwindSmallDebtNoOI_ZapNotPermitted_Fail() +// public +// selectFork(FORK["0p01_zap"]) +// { +// uint128 accountId = smallAccountIdNoOi; +// address accountOwner = smallAccountNoOiOwner; + +// uint256 tcvBefore = perpsMarket.totalCollateralValue(accountId); +// uint256 debt = perpsMarket.debt(accountId); +// uint256 collateralAmount = perpsMarket.getCollateralAmount(accountId, 4); +// uint256 wethBefore = weth.balanceOf(address(this)); +// uint256 usdcBefore = usdc.balanceOf(address(this)); + +// assertGt(tcvBefore, 0); +// assertGt(debt, 0); +// assertEq(perpsMarket.totalAccountOpenInterest(accountId), 0); + +// vm.startPrank(accountOwner); +// vm.expectRevert( +// abi.encodeWithSelector( +// IPerpsMarket.PermissionDenied.selector, +// 170_141_183_460_469_231_731_687_303_715_884_106_052, +// _PERPS_MODIFY_COLLATERAL_PERMISSION, +// 0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f +// ) +// ); +// zap.unwind( +// accountId, +// 4, +// collateralAmount, +// address(weth), +// swapData_0p001_zap, +// 0, +// 0, +// 0.001 ether, +// address(this) +// ); +// vm.stopPrank(); + +// assertEq(perpsMarket.debt(accountId), debt); +// assertEq(perpsMarket.totalCollateralValue(accountId), tcvBefore); +// assertEq(perpsMarket.totalAccountOpenInterest(accountId), 0); +// assertFalse( +// perpsMarket.hasPermission( +// accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) +// ) +// ); + +// assertEq(weth.balanceOf(address(this)), wethBefore); +// assertEq(usdc.balanceOf(address(this)), usdcBefore); + +// assertEq(weth.balanceOf(address(zap)), 0); +// assertEq(usdc.balanceOf(address(zap)), 0); +// assertEq(usdx.balanceOf(address(zap)), 0); +// } + +// error OnlyAave(address); + +// function testUnwindFailDirectCallback() +// public +// selectFork(FORK["0p01_zap"]) +// { +// vm.expectRevert( +// abi.encodeWithSelector(OnlyAave.selector, address(this)) +// ); +// zap.executeOperation(address(0), 0, 0, address(0), ""); +// } + +// error ReentrancyDetected(uint8, uint8); + +// function testUnwindFailDirectCallbackInvalidOrigin() +// public +// selectFork(FORK["0p01_zap"]) +// { +// vm.startPrank(ARBITRUM_AAVE_POOL); +// vm.expectRevert( +// abi.encodeWithSelector(ReentrancyDetected.selector, 0, 1) +// ); +// zap.executeOperation(address(0), 0, 0, address(0), ""); +// vm.stopPrank(); +// } + +// function testUnwindLargeDebtNoOI_Overpay_AccountOwner_Success() +// public +// selectFork(FORK["10_zap"]) +// { +// uint128 accountId = largeAccountIdNoOi; +// address accountOwner = largeAccountNoOiOwner; + +// uint256 tcvBefore = perpsMarket.totalCollateralValue(accountId); +// uint256 debt = perpsMarket.debt(accountId); +// uint256 collateralAmount = perpsMarket.getCollateralAmount(accountId, 4); +// uint256 wethBefore = weth.balanceOf(address(this)); +// uint256 usdcBefore = usdc.balanceOf(address(this)); + +// assertGt(tcvBefore, 0); +// assertGt(debt, 0); +// assertEq(perpsMarket.totalAccountOpenInterest(accountId), 0); + +// vm.startPrank(accountOwner); +// perpsMarket.grantPermission( +// accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) +// ); + +// zap.unwind( +// accountId, +// 4, // sETH collateral ID +// collateralAmount, +// address(weth), +// swapData_10_zap, +// 0, +// 0, +// 10 ether, +// address(this) +// ); +// vm.stopPrank(); + +// assertEq(perpsMarket.debt(accountId), 0); +// assertEq(perpsMarket.totalCollateralValue(accountId), 0); +// assertEq(perpsMarket.totalAccountOpenInterest(accountId), 0); +// assertFalse( +// perpsMarket.hasPermission( +// accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) +// ) +// ); + +// assertEq( +// weth.balanceOf(address(this)), +// wethBefore + collateralAmount - 10 ether +// ); +// assertGt( +// usdc.balanceOf(address(this)), +// usdcBefore + ((1000 - 2) * outAmount_10_zap / 1000) - (debt / 1e12) +// ); + +// assertEq(weth.balanceOf(address(zap)), 0); +// assertEq(usdc.balanceOf(address(zap)), 0); +// assertLt(usdx.balanceOf(address(zap)), 1 ether); +// } + +// function testUnwindLargeDebtWithOI_OverPay_AccountOwner_Success() +// public +// selectFork(FORK["10_zap"]) +// { +// uint128 accountId = largeAccountIdWithOi; +// address accountOwner = largeAccountWithOiOwner; + +// uint256 tcvBefore = perpsMarket.totalCollateralValue(accountId); +// uint256 debt = perpsMarket.debt(accountId); +// uint256 collateralAmount = perpsMarket.getCollateralAmount(accountId, 4); +// uint256 wethBefore = weth.balanceOf(address(this)); +// uint256 usdcBefore = usdc.balanceOf(address(this)); + +// assertGt(tcvBefore, 0); +// assertGt(debt, 0); +// assertGt(perpsMarket.totalAccountOpenInterest(accountId), 0); + +// vm.startPrank(accountOwner); +// perpsMarket.grantPermission( +// accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) +// ); + +// zap.unwind( +// accountId, +// 4, // sETH collateral ID +// 10 ether, +// address(weth), +// swapData_10_zap, +// 0, +// 0, +// 10 ether, +// address(this) +// ); +// vm.stopPrank(); + +// assertEq(perpsMarket.debt(accountId), 0); +// assertEq( +// perpsMarket.getCollateralAmount(accountId, 4), +// collateralAmount - 10 ether +// ); +// assertGt( +// perpsMarket.totalCollateralValue(accountId), +// tcvBefore - outValue_10_zap +// ); // this check is weak because the oracle price on this block is diff +// // from the odos api price +// assertGt(perpsMarket.totalAccountOpenInterest(accountId), 0); +// assertFalse( +// perpsMarket.hasPermission( +// accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) +// ) +// ); + +// assertEq(weth.balanceOf(address(this)), wethBefore); +// assertGt( +// usdc.balanceOf(address(this)), +// usdcBefore + ((1000 - 1) * outAmount_10_zap / 1000) - (debt / 1e12) +// ); + +// assertEq(weth.balanceOf(address(zap)), 0); +// assertEq(usdc.balanceOf(address(zap)), 0); +// assertLt(usdx.balanceOf(address(zap)), 1 ether); +// } + +// function testBurnSmallDebtNoOI_Exact_AccountOwner_Success() +// public +// selectFork(FORK["1_zap"]) +// { +// uint128 accountId = smallAccountIdNoOi; +// address accountOwner = smallAccountNoOiOwner; + +// // check account debt +// uint256 debt = perpsMarket.debt(accountId); + +// uint256 amount = debt; + +// _spin(accountOwner, usdx, amount); +// uint256 balanceBefore = usdx.balanceOf(accountOwner); + +// vm.startPrank(accountOwner); +// usdx.approve(address(zap), amount); +// zap.burn(amount, accountId); +// vm.stopPrank(); + +// assertEq(perpsMarket.debt(accountId), 0); +// assertEq(usdx.balanceOf(accountOwner), balanceBefore - debt); + +// assertEq(weth.balanceOf(address(zap)), 0); +// assertEq(usdc.balanceOf(address(zap)), 0); +// assertEq(usdx.balanceOf(address(zap)), 0); +// } + +// function testBurnSmallDebtNoOI_Exact_NotAccountOwner_Success() +// public +// selectFork(FORK["1_zap"]) +// { +// uint128 accountId = smallAccountIdNoOi; +// address user = vm.addr(1234); + +// // check account debt +// uint256 debt = perpsMarket.debt(accountId); + +// uint256 amount = debt; + +// _spin(user, usdx, amount); +// uint256 balanceBefore = usdx.balanceOf(user); + +// vm.startPrank(user); +// usdx.approve(address(zap), amount); +// zap.burn(amount, accountId); +// vm.stopPrank(); + +// assertEq(perpsMarket.debt(accountId), 0); +// assertEq(usdx.balanceOf(user), balanceBefore - debt); + +// assertEq(weth.balanceOf(address(zap)), 0); +// assertEq(usdc.balanceOf(address(zap)), 0); +// assertEq(usdx.balanceOf(address(zap)), 0); +// } + +// function testBurnSmallDebtNoOI_Overpay_AccountOwner_Success() +// public +// selectFork(FORK["1_zap"]) +// { +// uint128 accountId = smallAccountIdNoOi; +// address accountOwner = smallAccountNoOiOwner; + +// // check account debt +// uint256 debt = perpsMarket.debt(accountId); + +// uint256 amount = 123_456_789 + debt; + +// _spin(accountOwner, usdx, amount); +// uint256 balanceBefore = usdx.balanceOf(accountOwner); + +// vm.startPrank(accountOwner); +// usdx.approve(address(zap), amount); +// zap.burn(amount, accountId); +// vm.stopPrank(); + +// assertEq(perpsMarket.debt(accountId), 0); +// assertEq(usdx.balanceOf(accountOwner), balanceBefore - debt); +// assertEq(usdx.balanceOf(accountOwner), 123_456_789); + +// assertEq(weth.balanceOf(address(zap)), 0); +// assertEq(usdc.balanceOf(address(zap)), 0); +// assertEq(usdx.balanceOf(address(zap)), 0); +// } + +// function testBurnSmallDebtNoOI_Overpay_NotAccountOwner_Success() +// public +// selectFork(FORK["1_zap"]) +// { +// uint128 accountId = smallAccountIdNoOi; +// address user = vm.addr(1234); + +// // check account debt +// uint256 debt = perpsMarket.debt(accountId); - uint256 amount = 123_456_789 + debt; - - _spin(user, usdx, amount); - uint256 balanceBefore = usdx.balanceOf(user); +// uint256 amount = 123_456_789 + debt; + +// _spin(user, usdx, amount); +// uint256 balanceBefore = usdx.balanceOf(user); - vm.startPrank(user); - usdx.approve(address(zap), amount); - zap.burn(amount, accountId); - vm.stopPrank(); +// vm.startPrank(user); +// usdx.approve(address(zap), amount); +// zap.burn(amount, accountId); +// vm.stopPrank(); - assertEq(perpsMarket.debt(accountId), 0); - assertEq(usdx.balanceOf(user), balanceBefore - debt); - assertEq(usdx.balanceOf(user), 123_456_789); +// assertEq(perpsMarket.debt(accountId), 0); +// assertEq(usdx.balanceOf(user), balanceBefore - debt); +// assertEq(usdx.balanceOf(user), 123_456_789); - assertEq(weth.balanceOf(address(zap)), 0); - assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); - } +// assertEq(weth.balanceOf(address(zap)), 0); +// assertEq(usdc.balanceOf(address(zap)), 0); +// assertEq(usdx.balanceOf(address(zap)), 0); +// } - function testBurnSmallDebtNoOI_Partial_AccountOwner_Success() - public - selectFork(FORK["1_zap"]) - { - uint128 accountId = smallAccountIdNoOi; - address accountOwner = smallAccountNoOiOwner; +// function testBurnSmallDebtNoOI_Partial_AccountOwner_Success() +// public +// selectFork(FORK["1_zap"]) +// { +// uint128 accountId = smallAccountIdNoOi; +// address accountOwner = smallAccountNoOiOwner; - // check account debt - uint256 debt = perpsMarket.debt(accountId); - - uint256 amount = debt - 1e6; +// // check account debt +// uint256 debt = perpsMarket.debt(accountId); + +// uint256 amount = debt - 1e6; - _spin(accountOwner, usdx, amount); - uint256 balanceBefore = usdx.balanceOf(accountOwner); - - vm.startPrank(accountOwner); - usdx.approve(address(zap), amount); - zap.burn(amount, accountId); - vm.stopPrank(); +// _spin(accountOwner, usdx, amount); +// uint256 balanceBefore = usdx.balanceOf(accountOwner); + +// vm.startPrank(accountOwner); +// usdx.approve(address(zap), amount); +// zap.burn(amount, accountId); +// vm.stopPrank(); - assertEq(perpsMarket.debt(accountId), debt - balanceBefore); - assertEq(usdx.balanceOf(accountOwner), 0); +// assertEq(perpsMarket.debt(accountId), debt - balanceBefore); +// assertEq(usdx.balanceOf(accountOwner), 0); - assertEq(weth.balanceOf(address(zap)), 0); - assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); - } +// assertEq(weth.balanceOf(address(zap)), 0); +// assertEq(usdc.balanceOf(address(zap)), 0); +// assertEq(usdx.balanceOf(address(zap)), 0); +// } - function testBurnSmallDebtNoOI_Partial_NotAccountOwner_Success() - public - selectFork(FORK["1_zap"]) - { - uint128 accountId = smallAccountIdNoOi; - address user = vm.addr(1234); - - // check account debt - uint256 debt = perpsMarket.debt(accountId); - - uint256 amount = debt - 1e6; - - _spin(user, usdx, amount); - uint256 balanceBefore = usdx.balanceOf(user); - - vm.startPrank(user); - usdx.approve(address(zap), amount); - zap.burn(amount, accountId); - vm.stopPrank(); +// function testBurnSmallDebtNoOI_Partial_NotAccountOwner_Success() +// public +// selectFork(FORK["1_zap"]) +// { +// uint128 accountId = smallAccountIdNoOi; +// address user = vm.addr(1234); + +// // check account debt +// uint256 debt = perpsMarket.debt(accountId); + +// uint256 amount = debt - 1e6; + +// _spin(user, usdx, amount); +// uint256 balanceBefore = usdx.balanceOf(user); + +// vm.startPrank(user); +// usdx.approve(address(zap), amount); +// zap.burn(amount, accountId); +// vm.stopPrank(); - assertEq(perpsMarket.debt(accountId), debt - balanceBefore); - assertEq(usdx.balanceOf(user), 0); +// assertEq(perpsMarket.debt(accountId), debt - balanceBefore); +// assertEq(usdx.balanceOf(user), 0); - assertEq(weth.balanceOf(address(zap)), 0); - assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); - } +// assertEq(weth.balanceOf(address(zap)), 0); +// assertEq(usdc.balanceOf(address(zap)), 0); +// assertEq(usdx.balanceOf(address(zap)), 0); +// } - function testBurnSmallDebtWithOI_Exact_AccountOwner_Success() - public - selectFork(FORK["1_zap"]) - { - uint128 accountId = smallAccountIdWithOi; - address accountOwner = smallAccountWithOiOwner; - - // check account debt - uint256 debt = perpsMarket.debt(accountId); +// function testBurnSmallDebtWithOI_Exact_AccountOwner_Success() +// public +// selectFork(FORK["1_zap"]) +// { +// uint128 accountId = smallAccountIdWithOi; +// address accountOwner = smallAccountWithOiOwner; + +// // check account debt +// uint256 debt = perpsMarket.debt(accountId); - uint256 amount = debt; - - _spin(accountOwner, usdx, amount); - uint256 balanceBefore = usdx.balanceOf(accountOwner); +// uint256 amount = debt; + +// _spin(accountOwner, usdx, amount); +// uint256 balanceBefore = usdx.balanceOf(accountOwner); - vm.startPrank(accountOwner); - usdx.approve(address(zap), amount); - zap.burn(amount, accountId); - vm.stopPrank(); - - assertEq(perpsMarket.debt(accountId), 0); - assertEq(usdx.balanceOf(accountOwner), balanceBefore - debt); - - assertEq(weth.balanceOf(address(zap)), 0); - assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); - } - - function testBurnSmallDebtWithOI_Exact_NotAccountOwner_Success() - public - selectFork(FORK["1_zap"]) - { - uint128 accountId = smallAccountIdWithOi; - address user = vm.addr(1234); +// vm.startPrank(accountOwner); +// usdx.approve(address(zap), amount); +// zap.burn(amount, accountId); +// vm.stopPrank(); + +// assertEq(perpsMarket.debt(accountId), 0); +// assertEq(usdx.balanceOf(accountOwner), balanceBefore - debt); + +// assertEq(weth.balanceOf(address(zap)), 0); +// assertEq(usdc.balanceOf(address(zap)), 0); +// assertEq(usdx.balanceOf(address(zap)), 0); +// } + +// function testBurnSmallDebtWithOI_Exact_NotAccountOwner_Success() +// public +// selectFork(FORK["1_zap"]) +// { +// uint128 accountId = smallAccountIdWithOi; +// address user = vm.addr(1234); - // check account debt - uint256 debt = perpsMarket.debt(accountId); +// // check account debt +// uint256 debt = perpsMarket.debt(accountId); - uint256 amount = debt; - - _spin(user, usdx, amount); - uint256 balanceBefore = usdx.balanceOf(user); +// uint256 amount = debt; + +// _spin(user, usdx, amount); +// uint256 balanceBefore = usdx.balanceOf(user); - vm.startPrank(user); - usdx.approve(address(zap), amount); - zap.burn(amount, accountId); - vm.stopPrank(); - - assertEq(perpsMarket.debt(accountId), 0); - assertEq(usdx.balanceOf(user), balanceBefore - debt); +// vm.startPrank(user); +// usdx.approve(address(zap), amount); +// zap.burn(amount, accountId); +// vm.stopPrank(); + +// assertEq(perpsMarket.debt(accountId), 0); +// assertEq(usdx.balanceOf(user), balanceBefore - debt); - assertEq(weth.balanceOf(address(zap)), 0); - assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); - } +// assertEq(weth.balanceOf(address(zap)), 0); +// assertEq(usdc.balanceOf(address(zap)), 0); +// assertEq(usdx.balanceOf(address(zap)), 0); +// } - function testBurnSmallDebtWithOI_Overpay_AccountOwner_Success() - public - selectFork(FORK["1_zap"]) - { - uint128 accountId = smallAccountIdWithOi; - address accountOwner = smallAccountWithOiOwner; +// function testBurnSmallDebtWithOI_Overpay_AccountOwner_Success() +// public +// selectFork(FORK["1_zap"]) +// { +// uint128 accountId = smallAccountIdWithOi; +// address accountOwner = smallAccountWithOiOwner; - // check account debt - uint256 debt = perpsMarket.debt(accountId); +// // check account debt +// uint256 debt = perpsMarket.debt(accountId); - uint256 amount = 123_456_789 + debt; - - _spin(accountOwner, usdx, amount); - uint256 balanceBefore = usdx.balanceOf(accountOwner); +// uint256 amount = 123_456_789 + debt; + +// _spin(accountOwner, usdx, amount); +// uint256 balanceBefore = usdx.balanceOf(accountOwner); - vm.startPrank(accountOwner); - usdx.approve(address(zap), amount); - zap.burn(amount, accountId); - vm.stopPrank(); - - assertEq(perpsMarket.debt(accountId), 0); - assertEq(usdx.balanceOf(accountOwner), balanceBefore - debt); - assertEq(usdx.balanceOf(accountOwner), 123_456_789); +// vm.startPrank(accountOwner); +// usdx.approve(address(zap), amount); +// zap.burn(amount, accountId); +// vm.stopPrank(); + +// assertEq(perpsMarket.debt(accountId), 0); +// assertEq(usdx.balanceOf(accountOwner), balanceBefore - debt); +// assertEq(usdx.balanceOf(accountOwner), 123_456_789); - assertEq(weth.balanceOf(address(zap)), 0); - assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); - } +// assertEq(weth.balanceOf(address(zap)), 0); +// assertEq(usdc.balanceOf(address(zap)), 0); +// assertEq(usdx.balanceOf(address(zap)), 0); +// } - function testBurnSmallDebtWithOI_Overpay_NotAccountOwner_Success() - public - selectFork(FORK["1_zap"]) - { - uint128 accountId = smallAccountIdWithOi; - address user = vm.addr(1234); +// function testBurnSmallDebtWithOI_Overpay_NotAccountOwner_Success() +// public +// selectFork(FORK["1_zap"]) +// { +// uint128 accountId = smallAccountIdWithOi; +// address user = vm.addr(1234); - // check account debt - uint256 debt = perpsMarket.debt(accountId); +// // check account debt +// uint256 debt = perpsMarket.debt(accountId); - uint256 amount = 123_456_789 + debt; - - _spin(user, usdx, amount); - uint256 balanceBefore = usdx.balanceOf(user); +// uint256 amount = 123_456_789 + debt; + +// _spin(user, usdx, amount); +// uint256 balanceBefore = usdx.balanceOf(user); - vm.startPrank(user); - usdx.approve(address(zap), amount); - zap.burn(amount, accountId); - vm.stopPrank(); +// vm.startPrank(user); +// usdx.approve(address(zap), amount); +// zap.burn(amount, accountId); +// vm.stopPrank(); - assertEq(perpsMarket.debt(accountId), 0); - assertEq(usdx.balanceOf(user), balanceBefore - debt); - assertEq(usdx.balanceOf(user), 123_456_789); +// assertEq(perpsMarket.debt(accountId), 0); +// assertEq(usdx.balanceOf(user), balanceBefore - debt); +// assertEq(usdx.balanceOf(user), 123_456_789); - assertEq(weth.balanceOf(address(zap)), 0); - assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); - } +// assertEq(weth.balanceOf(address(zap)), 0); +// assertEq(usdc.balanceOf(address(zap)), 0); +// assertEq(usdx.balanceOf(address(zap)), 0); +// } - function testBurnSmallDebtWithOI_Partial_AccountOwner_Success() - public - selectFork(FORK["1_zap"]) - { - uint128 accountId = smallAccountIdWithOi; - address accountOwner = smallAccountWithOiOwner; +// function testBurnSmallDebtWithOI_Partial_AccountOwner_Success() +// public +// selectFork(FORK["1_zap"]) +// { +// uint128 accountId = smallAccountIdWithOi; +// address accountOwner = smallAccountWithOiOwner; - // check account debt - uint256 debt = perpsMarket.debt(accountId); - - uint256 amount = debt - 1e6; +// // check account debt +// uint256 debt = perpsMarket.debt(accountId); + +// uint256 amount = debt - 1e6; - _spin(accountOwner, usdx, amount); - uint256 balanceBefore = usdx.balanceOf(accountOwner); - - vm.startPrank(accountOwner); - usdx.approve(address(zap), amount); - zap.burn(amount, accountId); - vm.stopPrank(); +// _spin(accountOwner, usdx, amount); +// uint256 balanceBefore = usdx.balanceOf(accountOwner); + +// vm.startPrank(accountOwner); +// usdx.approve(address(zap), amount); +// zap.burn(amount, accountId); +// vm.stopPrank(); - assertEq(perpsMarket.debt(accountId), debt - balanceBefore); - assertEq(usdx.balanceOf(accountOwner), 0); +// assertEq(perpsMarket.debt(accountId), debt - balanceBefore); +// assertEq(usdx.balanceOf(accountOwner), 0); - assertEq(weth.balanceOf(address(zap)), 0); - assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); - } +// assertEq(weth.balanceOf(address(zap)), 0); +// assertEq(usdc.balanceOf(address(zap)), 0); +// assertEq(usdx.balanceOf(address(zap)), 0); +// } - function testBurnSmallDebtWithOI_Partial_NotAccountOwner_Success() - public - selectFork(FORK["1_zap"]) - { - uint128 accountId = smallAccountIdWithOi; - address user = vm.addr(1234); - - // check account debt - uint256 debt = perpsMarket.debt(accountId); - - uint256 amount = debt - 1e6; - - _spin(user, usdx, amount); - uint256 balanceBefore = usdx.balanceOf(user); - - vm.startPrank(user); - usdx.approve(address(zap), amount); - zap.burn(amount, accountId); - vm.stopPrank(); +// function testBurnSmallDebtWithOI_Partial_NotAccountOwner_Success() +// public +// selectFork(FORK["1_zap"]) +// { +// uint128 accountId = smallAccountIdWithOi; +// address user = vm.addr(1234); + +// // check account debt +// uint256 debt = perpsMarket.debt(accountId); + +// uint256 amount = debt - 1e6; + +// _spin(user, usdx, amount); +// uint256 balanceBefore = usdx.balanceOf(user); + +// vm.startPrank(user); +// usdx.approve(address(zap), amount); +// zap.burn(amount, accountId); +// vm.stopPrank(); - assertEq(perpsMarket.debt(accountId), debt - balanceBefore); - assertEq(usdx.balanceOf(user), 0); +// assertEq(perpsMarket.debt(accountId), debt - balanceBefore); +// assertEq(usdx.balanceOf(user), 0); - assertEq(weth.balanceOf(address(zap)), 0); - assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); - } +// assertEq(weth.balanceOf(address(zap)), 0); +// assertEq(usdc.balanceOf(address(zap)), 0); +// assertEq(usdx.balanceOf(address(zap)), 0); +// } - function testBurnLargeDebtNoOI_Exact_AccountOwner_Success() - public - selectFork(FORK["1_zap"]) - { - uint128 accountId = largeAccountIdNoOi; - address accountOwner = largeAccountNoOiOwner; - - // check account debt - uint256 debt = perpsMarket.debt(accountId); +// function testBurnLargeDebtNoOI_Exact_AccountOwner_Success() +// public +// selectFork(FORK["1_zap"]) +// { +// uint128 accountId = largeAccountIdNoOi; +// address accountOwner = largeAccountNoOiOwner; + +// // check account debt +// uint256 debt = perpsMarket.debt(accountId); - uint256 amount = debt; - - _spin(accountOwner, usdx, amount); - uint256 balanceBefore = usdx.balanceOf(accountOwner); +// uint256 amount = debt; + +// _spin(accountOwner, usdx, amount); +// uint256 balanceBefore = usdx.balanceOf(accountOwner); - vm.startPrank(accountOwner); - usdx.approve(address(zap), amount); - zap.burn(amount, accountId); - vm.stopPrank(); - - assertEq(perpsMarket.debt(accountId), 0); - assertEq(usdx.balanceOf(accountOwner), balanceBefore - debt); - - assertEq(weth.balanceOf(address(zap)), 0); - assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); - } - - function testBurnLargeDebtNoOI_Exact_NotAccountOwner_Success() - public - selectFork(FORK["1_zap"]) - { - uint128 accountId = largeAccountIdNoOi; - address user = vm.addr(1234); +// vm.startPrank(accountOwner); +// usdx.approve(address(zap), amount); +// zap.burn(amount, accountId); +// vm.stopPrank(); + +// assertEq(perpsMarket.debt(accountId), 0); +// assertEq(usdx.balanceOf(accountOwner), balanceBefore - debt); + +// assertEq(weth.balanceOf(address(zap)), 0); +// assertEq(usdc.balanceOf(address(zap)), 0); +// assertEq(usdx.balanceOf(address(zap)), 0); +// } + +// function testBurnLargeDebtNoOI_Exact_NotAccountOwner_Success() +// public +// selectFork(FORK["1_zap"]) +// { +// uint128 accountId = largeAccountIdNoOi; +// address user = vm.addr(1234); - // check account debt - uint256 debt = perpsMarket.debt(accountId); +// // check account debt +// uint256 debt = perpsMarket.debt(accountId); - uint256 amount = debt; - - _spin(user, usdx, amount); - uint256 balanceBefore = usdx.balanceOf(user); +// uint256 amount = debt; + +// _spin(user, usdx, amount); +// uint256 balanceBefore = usdx.balanceOf(user); - vm.startPrank(user); - usdx.approve(address(zap), amount); - zap.burn(amount, accountId); - vm.stopPrank(); - - assertEq(perpsMarket.debt(accountId), 0); - assertEq(usdx.balanceOf(user), balanceBefore - debt); +// vm.startPrank(user); +// usdx.approve(address(zap), amount); +// zap.burn(amount, accountId); +// vm.stopPrank(); + +// assertEq(perpsMarket.debt(accountId), 0); +// assertEq(usdx.balanceOf(user), balanceBefore - debt); - assertEq(weth.balanceOf(address(zap)), 0); - assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); - } +// assertEq(weth.balanceOf(address(zap)), 0); +// assertEq(usdc.balanceOf(address(zap)), 0); +// assertEq(usdx.balanceOf(address(zap)), 0); +// } - function testBurnLargeDebtNoOI_Overpay_AccountOwner_Success() - public - selectFork(FORK["1_zap"]) - { - uint128 accountId = largeAccountIdNoOi; - address accountOwner = largeAccountNoOiOwner; +// function testBurnLargeDebtNoOI_Overpay_AccountOwner_Success() +// public +// selectFork(FORK["1_zap"]) +// { +// uint128 accountId = largeAccountIdNoOi; +// address accountOwner = largeAccountNoOiOwner; - // check account debt - uint256 debt = perpsMarket.debt(accountId); +// // check account debt +// uint256 debt = perpsMarket.debt(accountId); - uint256 amount = 123_456_789 + debt; - - _spin(accountOwner, usdx, amount); - uint256 balanceBefore = usdx.balanceOf(accountOwner); +// uint256 amount = 123_456_789 + debt; + +// _spin(accountOwner, usdx, amount); +// uint256 balanceBefore = usdx.balanceOf(accountOwner); - vm.startPrank(accountOwner); - usdx.approve(address(zap), amount); - zap.burn(amount, accountId); - vm.stopPrank(); - - assertEq(perpsMarket.debt(accountId), 0); - assertEq(usdx.balanceOf(accountOwner), balanceBefore - debt); - assertEq(usdx.balanceOf(accountOwner), 123_456_789); +// vm.startPrank(accountOwner); +// usdx.approve(address(zap), amount); +// zap.burn(amount, accountId); +// vm.stopPrank(); + +// assertEq(perpsMarket.debt(accountId), 0); +// assertEq(usdx.balanceOf(accountOwner), balanceBefore - debt); +// assertEq(usdx.balanceOf(accountOwner), 123_456_789); - assertEq(weth.balanceOf(address(zap)), 0); - assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); - } +// assertEq(weth.balanceOf(address(zap)), 0); +// assertEq(usdc.balanceOf(address(zap)), 0); +// assertEq(usdx.balanceOf(address(zap)), 0); +// } - function testBurnLargeDebtNoOI_Overpay_NotAccountOwner_Success() - public - selectFork(FORK["1_zap"]) - { - uint128 accountId = largeAccountIdNoOi; - address user = vm.addr(1234); +// function testBurnLargeDebtNoOI_Overpay_NotAccountOwner_Success() +// public +// selectFork(FORK["1_zap"]) +// { +// uint128 accountId = largeAccountIdNoOi; +// address user = vm.addr(1234); - // check account debt - uint256 debt = perpsMarket.debt(accountId); +// // check account debt +// uint256 debt = perpsMarket.debt(accountId); - uint256 amount = 123_456_789 + debt; - - _spin(user, usdx, amount); - uint256 balanceBefore = usdx.balanceOf(user); +// uint256 amount = 123_456_789 + debt; + +// _spin(user, usdx, amount); +// uint256 balanceBefore = usdx.balanceOf(user); - vm.startPrank(user); - usdx.approve(address(zap), amount); - zap.burn(amount, accountId); - vm.stopPrank(); +// vm.startPrank(user); +// usdx.approve(address(zap), amount); +// zap.burn(amount, accountId); +// vm.stopPrank(); - assertEq(perpsMarket.debt(accountId), 0); - assertEq(usdx.balanceOf(user), balanceBefore - debt); - assertEq(usdx.balanceOf(user), 123_456_789); +// assertEq(perpsMarket.debt(accountId), 0); +// assertEq(usdx.balanceOf(user), balanceBefore - debt); +// assertEq(usdx.balanceOf(user), 123_456_789); - assertEq(weth.balanceOf(address(zap)), 0); - assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); - } +// assertEq(weth.balanceOf(address(zap)), 0); +// assertEq(usdc.balanceOf(address(zap)), 0); +// assertEq(usdx.balanceOf(address(zap)), 0); +// } - function testBurnLargeDebtNoOI_Partial_AccountOwner_Success() - public - selectFork(FORK["1_zap"]) - { - uint128 accountId = largeAccountIdNoOi; - address accountOwner = largeAccountNoOiOwner; +// function testBurnLargeDebtNoOI_Partial_AccountOwner_Success() +// public +// selectFork(FORK["1_zap"]) +// { +// uint128 accountId = largeAccountIdNoOi; +// address accountOwner = largeAccountNoOiOwner; - // check account debt - uint256 debt = perpsMarket.debt(accountId); - - uint256 amount = debt - 1e6; +// // check account debt +// uint256 debt = perpsMarket.debt(accountId); + +// uint256 amount = debt - 1e6; - _spin(accountOwner, usdx, amount); - uint256 balanceBefore = usdx.balanceOf(accountOwner); - - vm.startPrank(accountOwner); - usdx.approve(address(zap), amount); - zap.burn(amount, accountId); - vm.stopPrank(); +// _spin(accountOwner, usdx, amount); +// uint256 balanceBefore = usdx.balanceOf(accountOwner); + +// vm.startPrank(accountOwner); +// usdx.approve(address(zap), amount); +// zap.burn(amount, accountId); +// vm.stopPrank(); - assertEq(perpsMarket.debt(accountId), debt - balanceBefore); - assertEq(usdx.balanceOf(accountOwner), 0); +// assertEq(perpsMarket.debt(accountId), debt - balanceBefore); +// assertEq(usdx.balanceOf(accountOwner), 0); - assertEq(weth.balanceOf(address(zap)), 0); - assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); - } +// assertEq(weth.balanceOf(address(zap)), 0); +// assertEq(usdc.balanceOf(address(zap)), 0); +// assertEq(usdx.balanceOf(address(zap)), 0); +// } - function testBurnLargeDebtNoOI_Partial_NotAccountOwner_Success() - public - selectFork(FORK["1_zap"]) - { - uint128 accountId = largeAccountIdNoOi; - address user = vm.addr(1234); - - // check account debt - uint256 debt = perpsMarket.debt(accountId); - - uint256 amount = debt - 1e6; - - _spin(user, usdx, amount); - uint256 balanceBefore = usdx.balanceOf(user); - - vm.startPrank(user); - usdx.approve(address(zap), amount); - zap.burn(amount, accountId); - vm.stopPrank(); +// function testBurnLargeDebtNoOI_Partial_NotAccountOwner_Success() +// public +// selectFork(FORK["1_zap"]) +// { +// uint128 accountId = largeAccountIdNoOi; +// address user = vm.addr(1234); + +// // check account debt +// uint256 debt = perpsMarket.debt(accountId); + +// uint256 amount = debt - 1e6; + +// _spin(user, usdx, amount); +// uint256 balanceBefore = usdx.balanceOf(user); + +// vm.startPrank(user); +// usdx.approve(address(zap), amount); +// zap.burn(amount, accountId); +// vm.stopPrank(); - assertEq(perpsMarket.debt(accountId), debt - balanceBefore); - assertEq(usdx.balanceOf(user), 0); +// assertEq(perpsMarket.debt(accountId), debt - balanceBefore); +// assertEq(usdx.balanceOf(user), 0); - assertEq(weth.balanceOf(address(zap)), 0); - assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); - } +// assertEq(weth.balanceOf(address(zap)), 0); +// assertEq(usdc.balanceOf(address(zap)), 0); +// assertEq(usdx.balanceOf(address(zap)), 0); +// } - function testBurnLargeDebtWithOI_Exact_AccountOwner_Success() - public - selectFork(FORK["1_zap"]) - { - uint128 accountId = largeAccountIdWithOi; - address accountOwner = largeAccountWithOiOwner; - - // check account debt - uint256 debt = perpsMarket.debt(accountId); +// function testBurnLargeDebtWithOI_Exact_AccountOwner_Success() +// public +// selectFork(FORK["1_zap"]) +// { +// uint128 accountId = largeAccountIdWithOi; +// address accountOwner = largeAccountWithOiOwner; + +// // check account debt +// uint256 debt = perpsMarket.debt(accountId); - uint256 amount = debt; - - _spin(accountOwner, usdx, amount); - uint256 balanceBefore = usdx.balanceOf(accountOwner); +// uint256 amount = debt; + +// _spin(accountOwner, usdx, amount); +// uint256 balanceBefore = usdx.balanceOf(accountOwner); - vm.startPrank(accountOwner); - usdx.approve(address(zap), amount); - zap.burn(amount, accountId); - vm.stopPrank(); - - assertEq(perpsMarket.debt(accountId), 0); - assertEq(usdx.balanceOf(accountOwner), balanceBefore - debt); - - assertEq(weth.balanceOf(address(zap)), 0); - assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); - } - - function testBurnLargeDebtWithOI_Exact_NotAccountOwner_Success() - public - selectFork(FORK["1_zap"]) - { - uint128 accountId = largeAccountIdWithOi; - address user = vm.addr(1234); +// vm.startPrank(accountOwner); +// usdx.approve(address(zap), amount); +// zap.burn(amount, accountId); +// vm.stopPrank(); + +// assertEq(perpsMarket.debt(accountId), 0); +// assertEq(usdx.balanceOf(accountOwner), balanceBefore - debt); + +// assertEq(weth.balanceOf(address(zap)), 0); +// assertEq(usdc.balanceOf(address(zap)), 0); +// assertEq(usdx.balanceOf(address(zap)), 0); +// } + +// function testBurnLargeDebtWithOI_Exact_NotAccountOwner_Success() +// public +// selectFork(FORK["1_zap"]) +// { +// uint128 accountId = largeAccountIdWithOi; +// address user = vm.addr(1234); - // check account debt - uint256 debt = perpsMarket.debt(accountId); +// // check account debt +// uint256 debt = perpsMarket.debt(accountId); - uint256 amount = debt; - - _spin(user, usdx, amount); - uint256 balanceBefore = usdx.balanceOf(user); +// uint256 amount = debt; + +// _spin(user, usdx, amount); +// uint256 balanceBefore = usdx.balanceOf(user); - vm.startPrank(user); - usdx.approve(address(zap), amount); - zap.burn(amount, accountId); - vm.stopPrank(); - - assertEq(perpsMarket.debt(accountId), 0); - assertEq(usdx.balanceOf(user), balanceBefore - debt); +// vm.startPrank(user); +// usdx.approve(address(zap), amount); +// zap.burn(amount, accountId); +// vm.stopPrank(); + +// assertEq(perpsMarket.debt(accountId), 0); +// assertEq(usdx.balanceOf(user), balanceBefore - debt); - assertEq(weth.balanceOf(address(zap)), 0); - assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); - } +// assertEq(weth.balanceOf(address(zap)), 0); +// assertEq(usdc.balanceOf(address(zap)), 0); +// assertEq(usdx.balanceOf(address(zap)), 0); +// } - function testBurnLargeDebtWithOI_Overpay_AccountOwner_Success() - public - selectFork(FORK["1_zap"]) - { - uint128 accountId = largeAccountIdWithOi; - address accountOwner = largeAccountWithOiOwner; +// function testBurnLargeDebtWithOI_Overpay_AccountOwner_Success() +// public +// selectFork(FORK["1_zap"]) +// { +// uint128 accountId = largeAccountIdWithOi; +// address accountOwner = largeAccountWithOiOwner; - // check account debt - uint256 debt = perpsMarket.debt(accountId); +// // check account debt +// uint256 debt = perpsMarket.debt(accountId); - uint256 amount = 123_456_789 + debt; - - _spin(accountOwner, usdx, amount); - uint256 balanceBefore = usdx.balanceOf(accountOwner); +// uint256 amount = 123_456_789 + debt; + +// _spin(accountOwner, usdx, amount); +// uint256 balanceBefore = usdx.balanceOf(accountOwner); - vm.startPrank(accountOwner); - usdx.approve(address(zap), amount); - zap.burn(amount, accountId); - vm.stopPrank(); +// vm.startPrank(accountOwner); +// usdx.approve(address(zap), amount); +// zap.burn(amount, accountId); +// vm.stopPrank(); - assertEq(perpsMarket.debt(accountId), 0); - assertEq(usdx.balanceOf(accountOwner), balanceBefore - debt); - assertEq(usdx.balanceOf(accountOwner), 123_456_789); +// assertEq(perpsMarket.debt(accountId), 0); +// assertEq(usdx.balanceOf(accountOwner), balanceBefore - debt); +// assertEq(usdx.balanceOf(accountOwner), 123_456_789); - assertEq(weth.balanceOf(address(zap)), 0); - assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); - } +// assertEq(weth.balanceOf(address(zap)), 0); +// assertEq(usdc.balanceOf(address(zap)), 0); +// assertEq(usdx.balanceOf(address(zap)), 0); +// } - function testBurnLargeDebtWithOI_Overpay_NotAccountOwner_Success() - public - selectFork(FORK["1_zap"]) - { - uint128 accountId = largeAccountIdWithOi; - address user = vm.addr(1234); +// function testBurnLargeDebtWithOI_Overpay_NotAccountOwner_Success() +// public +// selectFork(FORK["1_zap"]) +// { +// uint128 accountId = largeAccountIdWithOi; +// address user = vm.addr(1234); - // check account debt - uint256 debt = perpsMarket.debt(accountId); +// // check account debt +// uint256 debt = perpsMarket.debt(accountId); - uint256 amount = 123_456_789 + debt; +// uint256 amount = 123_456_789 + debt; - _spin(user, usdx, amount); - uint256 balanceBefore = usdx.balanceOf(user); +// _spin(user, usdx, amount); +// uint256 balanceBefore = usdx.balanceOf(user); - vm.startPrank(user); - usdx.approve(address(zap), amount); - zap.burn(amount, accountId); - vm.stopPrank(); +// vm.startPrank(user); +// usdx.approve(address(zap), amount); +// zap.burn(amount, accountId); +// vm.stopPrank(); - assertEq(perpsMarket.debt(accountId), 0); - assertEq(usdx.balanceOf(user), balanceBefore - debt); - assertEq(usdx.balanceOf(user), 123_456_789); +// assertEq(perpsMarket.debt(accountId), 0); +// assertEq(usdx.balanceOf(user), balanceBefore - debt); +// assertEq(usdx.balanceOf(user), 123_456_789); - assertEq(weth.balanceOf(address(zap)), 0); - assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); - } +// assertEq(weth.balanceOf(address(zap)), 0); +// assertEq(usdc.balanceOf(address(zap)), 0); +// assertEq(usdx.balanceOf(address(zap)), 0); +// } - function testBurnLargeDebtWithOI_Partial_AccountOwner_Success() - public - selectFork(FORK["1_zap"]) - { - uint128 accountId = largeAccountIdWithOi; - address accountOwner = largeAccountWithOiOwner; +// function testBurnLargeDebtWithOI_Partial_AccountOwner_Success() +// public +// selectFork(FORK["1_zap"]) +// { +// uint128 accountId = largeAccountIdWithOi; +// address accountOwner = largeAccountWithOiOwner; - // check account debt - uint256 debt = perpsMarket.debt(accountId); +// // check account debt +// uint256 debt = perpsMarket.debt(accountId); - uint256 amount = debt - 1e6; +// uint256 amount = debt - 1e6; - _spin(accountOwner, usdx, amount); - uint256 balanceBefore = usdx.balanceOf(accountOwner); +// _spin(accountOwner, usdx, amount); +// uint256 balanceBefore = usdx.balanceOf(accountOwner); - vm.startPrank(accountOwner); - usdx.approve(address(zap), amount); - zap.burn(amount, accountId); - vm.stopPrank(); +// vm.startPrank(accountOwner); +// usdx.approve(address(zap), amount); +// zap.burn(amount, accountId); +// vm.stopPrank(); - assertEq(perpsMarket.debt(accountId), debt - balanceBefore); - assertEq(usdx.balanceOf(accountOwner), 0); +// assertEq(perpsMarket.debt(accountId), debt - balanceBefore); +// assertEq(usdx.balanceOf(accountOwner), 0); - assertEq(weth.balanceOf(address(zap)), 0); - assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); - } +// assertEq(weth.balanceOf(address(zap)), 0); +// assertEq(usdc.balanceOf(address(zap)), 0); +// assertEq(usdx.balanceOf(address(zap)), 0); +// } - function testBurnLargeDebtWithOI_Partial_NotAccountOwner_Success() - public - selectFork(FORK["1_zap"]) - { - uint128 accountId = largeAccountIdWithOi; - address user = vm.addr(1234); +// function testBurnLargeDebtWithOI_Partial_NotAccountOwner_Success() +// public +// selectFork(FORK["1_zap"]) +// { +// uint128 accountId = largeAccountIdWithOi; +// address user = vm.addr(1234); - // check account debt - uint256 debt = perpsMarket.debt(accountId); +// // check account debt +// uint256 debt = perpsMarket.debt(accountId); - uint256 amount = debt - 1e6; +// uint256 amount = debt - 1e6; - _spin(user, usdx, amount); - uint256 balanceBefore = usdx.balanceOf(user); +// _spin(user, usdx, amount); +// uint256 balanceBefore = usdx.balanceOf(user); - vm.startPrank(user); - usdx.approve(address(zap), amount); - zap.burn(amount, accountId); - vm.stopPrank(); +// vm.startPrank(user); +// usdx.approve(address(zap), amount); +// zap.burn(amount, accountId); +// vm.stopPrank(); - assertEq(perpsMarket.debt(accountId), debt - balanceBefore); - assertEq(usdx.balanceOf(user), 0); +// assertEq(perpsMarket.debt(accountId), debt - balanceBefore); +// assertEq(usdx.balanceOf(user), 0); - assertEq(weth.balanceOf(address(zap)), 0); - assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); - } +// assertEq(weth.balanceOf(address(zap)), 0); +// assertEq(usdc.balanceOf(address(zap)), 0); +// assertEq(usdx.balanceOf(address(zap)), 0); +// } - // TODO fix plumber tests - - function testFlush_Plumber_Success() public selectFork(FORK["1_zap"]) { - uint256 amountWeth = 1234 ether; - uint256 amountUsdx = 56_789 ether; - _spin(address(zap), weth, amountWeth); - _spin(address(zap), usdx, amountUsdx); - - uint256 zapWethBefore = weth.balanceOf(address(zap)); - uint256 zapUsdxBefore = usdx.balanceOf(address(zap)); - - uint256 plumberWethBefore = weth.balanceOf(address(this)); - uint256 plumberUsdxBefore = usdx.balanceOf(address(this)); - - // this test contract created the Zap contract and should be the owner - zap.flush(address(usdx)); - - assertEq(usdx.balanceOf(address(zap)), 0); - assertEq(weth.balanceOf(address(zap)), zapWethBefore); +// // TODO fix plumber tests + +// function testFlush_Plumber_Success() public selectFork(FORK["1_zap"]) { +// uint256 amountWeth = 1234 ether; +// uint256 amountUsdx = 56_789 ether; +// _spin(address(zap), weth, amountWeth); +// _spin(address(zap), usdx, amountUsdx); + +// uint256 zapWethBefore = weth.balanceOf(address(zap)); +// uint256 zapUsdxBefore = usdx.balanceOf(address(zap)); + +// uint256 plumberWethBefore = weth.balanceOf(address(this)); +// uint256 plumberUsdxBefore = usdx.balanceOf(address(this)); + +// // this test contract created the Zap contract and should be the owner +// zap.flush(address(usdx)); + +// assertEq(usdx.balanceOf(address(zap)), 0); +// assertEq(weth.balanceOf(address(zap)), zapWethBefore); - assertEq( - usdx.balanceOf(address(this)), plumberUsdxBefore + zapUsdxBefore - ); - assertEq(weth.balanceOf(address(this)), plumberWethBefore); +// assertEq( +// usdx.balanceOf(address(this)), plumberUsdxBefore + zapUsdxBefore +// ); +// assertEq(weth.balanceOf(address(this)), plumberWethBefore); - zap.flush(address(weth)); - - assertEq(usdx.balanceOf(address(zap)), 0); - assertEq(weth.balanceOf(address(zap)), 0); - - assertEq( - usdx.balanceOf(address(this)), plumberUsdxBefore + zapUsdxBefore - ); - assertEq( - weth.balanceOf(address(this)), plumberWethBefore + zapWethBefore - ); - } - - error OnlyPlumber(); - - function testFlush_NotPlumberer_Fail() public selectFork(FORK["1_zap"]) { - uint256 amountWeth = 1234 ether; - uint256 amountUsdx = 56_789 ether; - _spin(address(zap), weth, amountWeth); - _spin(address(zap), usdx, amountUsdx); - - uint256 zapWethBefore = weth.balanceOf(address(zap)); - uint256 zapUsdxBefore = usdx.balanceOf(address(zap)); - - uint256 plumberWethBefore = weth.balanceOf(address(this)); - uint256 plumberUsdxBefore = usdx.balanceOf(address(this)); - - // this test contract created the Zap contract and should be the owner - vm.prank(vm.addr(987_654_321)); - vm.expectRevert(abi.encodeWithSelector(OnlyPlumber.selector)); - zap.flush(address(usdx)); - - assertEq(usdx.balanceOf(address(zap)), zapUsdxBefore); - assertEq(weth.balanceOf(address(zap)), zapWethBefore); - - assertEq(usdx.balanceOf(address(this)), plumberUsdxBefore); - assertEq(weth.balanceOf(address(this)), plumberWethBefore); - } - - function testFlushNominate_Plumber_Success() - public - selectFork(FORK["1_zap"]) - { - address currentPlumber = zap.PLUMBER(); - address nominated = address(0xdeadbeef); - - assertGt(uint160(currentPlumber), 0); - - zap.nominatePlumber(nominated); - - address nominatedPlumber = zap.nominatedPlumber(); - assertEq(nominatedPlumber, nominated); - assertEq(currentPlumber, zap.PLUMBER()); - - vm.prank(nominated); - zap.acceptPlumberNomination(); - address newPlumber = zap.PLUMBER(); - assertEq(nominated, newPlumber); - } - - function testFlushDesignate_NotPlumber_Fail() - public - selectFork(FORK["1_zap"]) - { - address currentPlumber = zap.PLUMBER(); - address nominated = address(0); - - assertGt(uint160(currentPlumber), 0); - - vm.prank(vm.addr(987_654_321)); - vm.expectRevert(abi.encodeWithSelector(OnlyPlumber.selector)); - zap.nominatePlumber(nominated); - - address newPlumber = zap.PLUMBER(); - assertEq(newPlumber, currentPlumber); - assertGt(uint160(newPlumber), 0); - } - - function testWithdrawNoOiNoDebt_AllCollateral_AccountOwner_Success() - public - selectFork(FORK["1_zap"]) - { - address user = vm.addr(5); - uint32 amount = 1_000_000_000; - _spin(user, usdx, amount); - - vm.startPrank(user); - uint128 accountId = perpsMarket.createAccount(); - int128 margin = int128(int32(amount)); - - usdx.approve(address(perpsMarket), amount); - perpsMarket.modifyCollateral(accountId, 0, margin); - - assertEq(usdx.balanceOf(user), 0); - assertEq(perpsMarket.totalCollateralValue(accountId), amount); - - perpsMarket.grantPermission( - accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) - ); - zap.withdraw({ - _synthId: 0, - _amount: amount, - _accountId: accountId, - _receiver: user - }); - vm.stopPrank(); - - assertEq(usdx.balanceOf(user), amount); - assertEq(perpsMarket.totalCollateralValue(accountId), 0); - - assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(susdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); - assertFalse( - perpsMarket.isAuthorized( - accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) - ) - ); - } - - function testWithdrawNoOiNoDebt_AllCollateral_NotAccounttOwner_Fail() - public - selectFork(FORK["1_zap"]) - { - address user = vm.addr(5); - uint32 amount = 1_000_000_000; - _spin(user, usdx, amount); - - vm.startPrank(user); - uint128 accountId = perpsMarket.createAccount(); - int128 margin = int128(int32(amount)); - - usdx.approve(address(perpsMarket), amount); - perpsMarket.modifyCollateral(accountId, 0, margin); - - assertEq(usdx.balanceOf(user), 0); - - perpsMarket.grantPermission( - accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) - ); - vm.stopPrank(); - - vm.expectRevert(abi.encodeWithSelector(NotPermitted.selector)); - zap.withdraw({ - _synthId: 0, - _amount: amount, - _accountId: accountId, - _receiver: user - }); - - assertEq(usdx.balanceOf(user), 0); - assertEq(perpsMarket.totalCollateralValue(accountId), amount); - - assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(susdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); - assertTrue( - perpsMarket.isAuthorized( - accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) - ) - ); - } - - function testWithdrawNoOiNoDebt_AccountOwner_ZapNotPermitted_Fail() - public - selectFork(FORK["1_zap"]) - { - address user = vm.addr(5); - uint32 amount = 1_000_000_000; - _spin(user, usdx, amount); - - vm.startPrank(user); - uint128 accountId = perpsMarket.createAccount(); - int128 margin = int128(int32(amount)); - - usdx.approve(address(perpsMarket), amount); - perpsMarket.modifyCollateral(accountId, 0, margin); - - assertEq(usdx.balanceOf(user), 0); - assertEq(perpsMarket.totalCollateralValue(accountId), amount); - - vm.expectRevert( - abi.encodeWithSelector( - IPerpsMarket.PermissionDenied.selector, - accountId, - _PERPS_MODIFY_COLLATERAL_PERMISSION, - address(zap) - ) - ); - zap.withdraw({ - _synthId: 0, - _amount: amount, - _accountId: accountId, - _receiver: user - }); - - vm.stopPrank(); - - assertEq(usdx.balanceOf(user), 0); - assertEq(perpsMarket.totalCollateralValue(accountId), amount); - - assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(susdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); - assertFalse( - perpsMarket.isAuthorized( - accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) - ) - ); - } - - // Basic functional tests, these are similar to existing tests and were used - // to ensure this harness worked correctly - function testBuySuccess(uint128 amount) public selectFork(FORK["1_zap"]) { - // D18, fuzzing up to 3e38 - vm.assume(amount < uint128(type(int128).max / 9)); - vm.assume(amount > 10); - - address user = vm.addr(1); - // uint256 amount = 1000e6; - - _spin(user, usdx, amount); - - assertEq(usdx.balanceOf(user), amount); - assertEq(susdc.balanceOf(user), 0); - - vm.startPrank(user); - usdx.approve(address(zap), amount); - - (uint256 received, address synth) = zap.buy({ - _synthId: zap.SUSDC_SPOT_ID(), - _amount: amount, - _minAmountOut: 0, - _receiver: user - }); - vm.stopPrank(); - - assertEq(synth, address(susdc)); - assertGe(received, amount * 9 / 10); - assertEq(usdx.balanceOf(user), 0); - assertGe(susdc.balanceOf(user), amount * 9 / 10); - - assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(susdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); - } - - function testSellSuccess( /*uint128 amount*/ ) - public - selectFork(FORK["1_zap"]) - { - address user = vm.addr(2); - // _maxCoreCapacity(); - // vm.assume(amount < 1e20); - uint256 amount = 1000e18; - uint256 minAmountOut = amount * 99 / 100; - _spin(user, usdx, amount); - - vm.startPrank(user); - usdx.approve(address(zap), amount); - - (uint256 received,) = zap.buy({ - _synthId: zap.SUSDC_SPOT_ID(), - _amount: amount, - _minAmountOut: minAmountOut, - _receiver: user - }); - - assertEq(usdx.balanceOf(user), 0); - assertEq(usdc.balanceOf(user), 0); - assertEq(susdc.balanceOf(user), received); - assertGe(received, minAmountOut); - assertGe(susdc.balanceOf(user), minAmountOut); - - susdc.approve(address(zap), received); - minAmountOut = received * 99 / 100; - - received = zap.sell({ - _synthId: zap.SUSDC_SPOT_ID(), - _amount: received, - _minAmountOut: minAmountOut, - _receiver: user - }); - vm.stopPrank(); - - assertGe(usdx.balanceOf(user), minAmountOut); - assertGe(received, minAmountOut); - assertEq(usdx.balanceOf(user), received); - assertEq(susdc.balanceOf(user), 0); - - assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(susdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); - } - - function testUnwrap( /* uint32 amount */ ) - public - selectFork(FORK["1_zap"]) - { - address user = vm.addr(4); - uint256 amount = 1000e6; - _spin(user, usdc, amount); - - vm.startPrank(user); - usdc.approve(address(zap), amount); - - uint256 wrapped = zap.wrap({ - _token: address(usdc), - _synthId: zap.SUSDC_SPOT_ID(), - _amount: amount, - _minAmountOut: amount, - _receiver: user - }); - - assertEq(usdc.balanceOf(user), 0); - assertEq(wrapped, amount * 1e12); - assertEq(susdc.balanceOf(user), amount * 1e12); - - susdc.approve(address(zap), type(uint256).max); - - uint256 unwrapped = zap.unwrap({ - _token: address(usdc), - _synthId: zap.SUSDC_SPOT_ID(), - _amount: wrapped, - _minAmountOut: amount, - _receiver: user - }); - vm.stopPrank(); - - assertEq(unwrapped, amount); - assertEq(usdc.balanceOf(user), amount); - assertEq(susdc.balanceOf(user), 0); - - assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(susdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); - } - - function testWrap( /*uint64 amount*/ ) public selectFork(FORK["1_zap"]) { - address user = vm.addr(6); - uint64 amount = 1000e6; - _spin(user, usdc, amount); - - assertEq(usdc.balanceOf(user), amount); - assertEq(susdc.balanceOf(user), 0); - - vm.startPrank(user); - usdc.approve(address(zap), amount); - - uint256 wrapped = zap.wrap({ - _token: address(usdc), - _synthId: zap.SUSDC_SPOT_ID(), - _amount: amount, - _minAmountOut: amount, - _receiver: user - }); - vm.stopPrank(); - - assertEq(wrapped, uint256(amount) * 1e12); - assertEq(usdc.balanceOf(user), 0); - assertEq(susdc.balanceOf(user), wrapped); - - assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(susdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); - } - - function testZapInSuccess( /*uint64 amount*/ ) - public - selectFork(FORK["1_zap"]) - { - address user = vm.addr(7); - uint64 amount = 1000e6; - _spin(user, usdc, amount); - - assertEq(usdc.balanceOf(user), amount); - assertEq(usdx.balanceOf(user), 0); - - vm.startPrank(user); - usdc.approve(address(zap), amount); - - uint256 zapped = - zap.zapIn({_amount: amount, _minAmountOut: amount, _receiver: user}); - vm.stopPrank(); - - assertGe(zapped, uint256(amount) * 99e10); // amount * 1e12 * 0.99 - assertEq(usdc.balanceOf(user), 0); - assertEq(usdx.balanceOf(user), zapped); - - assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(susdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); - } - - function testZapOutSuccess( /*uint64 amount*/ ) - public - selectFork(FORK["1_zap"]) - { - address user = vm.addr(8); - // vm.assume(amount > 1e12); - uint256 amount = 250e18; - _spin(address(this), usdc, amount / 1e12); - usdc.approve(address(zap), amount / 1e12); - zap.wrap({ - _token: address(usdc), - _synthId: zap.SUSDC_SPOT_ID(), - _amount: amount / 1e12, - _minAmountOut: amount / 1e12, - _receiver: address(this) - }); - assertEq(usdc.balanceOf(address(this)), 0); - assertEq(susdc.balanceOf(address(this)), amount); - - _spin(user, usdx, amount); - - assertEq(usdc.balanceOf(user), 0); - assertEq(usdx.balanceOf(user), amount); - - vm.startPrank(user); - usdx.approve(address(zap), amount); - - uint256 zapped = zap.zapOut({ - _amount: amount, - _minAmountOut: amount * 9 / 1e13, - _receiver: user - }); - vm.stopPrank(); - - assertGe(zapped * 1e12, amount * 9 / 10); - assertEq(usdc.balanceOf(user), zapped); - assertEq(usdx.balanceOf(user), 0); - - assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(susdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); - } - -} +// zap.flush(address(weth)); + +// assertEq(usdx.balanceOf(address(zap)), 0); +// assertEq(weth.balanceOf(address(zap)), 0); + +// assertEq( +// usdx.balanceOf(address(this)), plumberUsdxBefore + zapUsdxBefore +// ); +// assertEq( +// weth.balanceOf(address(this)), plumberWethBefore + zapWethBefore +// ); +// } + +// error OnlyPlumber(); + +// function testFlush_NotPlumberer_Fail() public selectFork(FORK["1_zap"]) { +// uint256 amountWeth = 1234 ether; +// uint256 amountUsdx = 56_789 ether; +// _spin(address(zap), weth, amountWeth); +// _spin(address(zap), usdx, amountUsdx); + +// uint256 zapWethBefore = weth.balanceOf(address(zap)); +// uint256 zapUsdxBefore = usdx.balanceOf(address(zap)); + +// uint256 plumberWethBefore = weth.balanceOf(address(this)); +// uint256 plumberUsdxBefore = usdx.balanceOf(address(this)); + +// // this test contract created the Zap contract and should be the owner +// vm.prank(vm.addr(987_654_321)); +// vm.expectRevert(abi.encodeWithSelector(OnlyPlumber.selector)); +// zap.flush(address(usdx)); + +// assertEq(usdx.balanceOf(address(zap)), zapUsdxBefore); +// assertEq(weth.balanceOf(address(zap)), zapWethBefore); + +// assertEq(usdx.balanceOf(address(this)), plumberUsdxBefore); +// assertEq(weth.balanceOf(address(this)), plumberWethBefore); +// } + +// function testFlushNominate_Plumber_Success() +// public +// selectFork(FORK["1_zap"]) +// { +// address currentPlumber = zap.PLUMBER(); +// address nominated = address(0xdeadbeef); + +// assertGt(uint160(currentPlumber), 0); + +// zap.nominatePlumber(nominated); + +// address nominatedPlumber = zap.nominatedPlumber(); +// assertEq(nominatedPlumber, nominated); +// assertEq(currentPlumber, zap.PLUMBER()); + +// vm.prank(nominated); +// zap.acceptPlumberNomination(); +// address newPlumber = zap.PLUMBER(); +// assertEq(nominated, newPlumber); +// } + +// function testFlushDesignate_NotPlumber_Fail() +// public +// selectFork(FORK["1_zap"]) +// { +// address currentPlumber = zap.PLUMBER(); +// address nominated = address(0); + +// assertGt(uint160(currentPlumber), 0); + +// vm.prank(vm.addr(987_654_321)); +// vm.expectRevert(abi.encodeWithSelector(OnlyPlumber.selector)); +// zap.nominatePlumber(nominated); + +// address newPlumber = zap.PLUMBER(); +// assertEq(newPlumber, currentPlumber); +// assertGt(uint160(newPlumber), 0); +// } + +// function testWithdrawNoOiNoDebt_AllCollateral_AccountOwner_Success() +// public +// selectFork(FORK["1_zap"]) +// { +// address user = vm.addr(5); +// uint32 amount = 1_000_000_000; +// _spin(user, usdx, amount); + +// vm.startPrank(user); +// uint128 accountId = perpsMarket.createAccount(); +// int128 margin = int128(int32(amount)); + +// usdx.approve(address(perpsMarket), amount); +// perpsMarket.modifyCollateral(accountId, 0, margin); + +// assertEq(usdx.balanceOf(user), 0); +// assertEq(perpsMarket.totalCollateralValue(accountId), amount); + +// perpsMarket.grantPermission( +// accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) +// ); +// zap.withdraw({ +// _synthId: 0, +// _amount: amount, +// _accountId: accountId, +// _receiver: user +// }); +// vm.stopPrank(); + +// assertEq(usdx.balanceOf(user), amount); +// assertEq(perpsMarket.totalCollateralValue(accountId), 0); + +// assertEq(usdc.balanceOf(address(zap)), 0); +// assertEq(susdc.balanceOf(address(zap)), 0); +// assertEq(usdx.balanceOf(address(zap)), 0); +// assertFalse( +// perpsMarket.isAuthorized( +// accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) +// ) +// ); +// } + +// function testWithdrawNoOiNoDebt_AllCollateral_NotAccounttOwner_Fail() +// public +// selectFork(FORK["1_zap"]) +// { +// address user = vm.addr(5); +// uint32 amount = 1_000_000_000; +// _spin(user, usdx, amount); + +// vm.startPrank(user); +// uint128 accountId = perpsMarket.createAccount(); +// int128 margin = int128(int32(amount)); + +// usdx.approve(address(perpsMarket), amount); +// perpsMarket.modifyCollateral(accountId, 0, margin); + +// assertEq(usdx.balanceOf(user), 0); + +// perpsMarket.grantPermission( +// accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) +// ); +// vm.stopPrank(); + +// vm.expectRevert(abi.encodeWithSelector(NotPermitted.selector)); +// zap.withdraw({ +// _synthId: 0, +// _amount: amount, +// _accountId: accountId, +// _receiver: user +// }); + +// assertEq(usdx.balanceOf(user), 0); +// assertEq(perpsMarket.totalCollateralValue(accountId), amount); + +// assertEq(usdc.balanceOf(address(zap)), 0); +// assertEq(susdc.balanceOf(address(zap)), 0); +// assertEq(usdx.balanceOf(address(zap)), 0); +// assertTrue( +// perpsMarket.isAuthorized( +// accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) +// ) +// ); +// } + +// function testWithdrawNoOiNoDebt_AccountOwner_ZapNotPermitted_Fail() +// public +// selectFork(FORK["1_zap"]) +// { +// address user = vm.addr(5); +// uint32 amount = 1_000_000_000; +// _spin(user, usdx, amount); + +// vm.startPrank(user); +// uint128 accountId = perpsMarket.createAccount(); +// int128 margin = int128(int32(amount)); + +// usdx.approve(address(perpsMarket), amount); +// perpsMarket.modifyCollateral(accountId, 0, margin); + +// assertEq(usdx.balanceOf(user), 0); +// assertEq(perpsMarket.totalCollateralValue(accountId), amount); + +// vm.expectRevert( +// abi.encodeWithSelector( +// IPerpsMarket.PermissionDenied.selector, +// accountId, +// _PERPS_MODIFY_COLLATERAL_PERMISSION, +// address(zap) +// ) +// ); +// zap.withdraw({ +// _synthId: 0, +// _amount: amount, +// _accountId: accountId, +// _receiver: user +// }); + +// vm.stopPrank(); + +// assertEq(usdx.balanceOf(user), 0); +// assertEq(perpsMarket.totalCollateralValue(accountId), amount); + +// assertEq(usdc.balanceOf(address(zap)), 0); +// assertEq(susdc.balanceOf(address(zap)), 0); +// assertEq(usdx.balanceOf(address(zap)), 0); +// assertFalse( +// perpsMarket.isAuthorized( +// accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) +// ) +// ); +// } + +// // Basic functional tests, these are similar to existing tests and were used +// // to ensure this harness worked correctly +// function testBuySuccess(uint128 amount) public selectFork(FORK["1_zap"]) { +// // D18, fuzzing up to 3e38 +// vm.assume(amount < uint128(type(int128).max / 9)); +// vm.assume(amount > 10); + +// address user = vm.addr(1); +// // uint256 amount = 1000e6; + +// _spin(user, usdx, amount); + +// assertEq(usdx.balanceOf(user), amount); +// assertEq(susdc.balanceOf(user), 0); + +// vm.startPrank(user); +// usdx.approve(address(zap), amount); + +// (uint256 received, address synth) = zap.buy({ +// _synthId: zap.SSTATA_SPOT_ID(), +// _amount: amount, +// _minAmountOut: 0, +// _receiver: user +// }); +// vm.stopPrank(); + +// assertEq(synth, address(susdc)); +// assertGe(received, amount * 9 / 10); +// assertEq(usdx.balanceOf(user), 0); +// assertGe(susdc.balanceOf(user), amount * 9 / 10); + +// assertEq(usdc.balanceOf(address(zap)), 0); +// assertEq(susdc.balanceOf(address(zap)), 0); +// assertEq(usdx.balanceOf(address(zap)), 0); +// } + +// function testSellSuccess( /*uint128 amount*/ ) +// public +// selectFork(FORK["1_zap"]) +// { +// address user = vm.addr(2); +// // _maxCoreCapacity(); +// // vm.assume(amount < 1e20); +// uint256 amount = 1000e18; +// uint256 minAmountOut = amount * 99 / 100; +// _spin(user, usdx, amount); + +// vm.startPrank(user); +// usdx.approve(address(zap), amount); + +// (uint256 received,) = zap.buy({ +// _synthId: zap.SSTATA_SPOT_ID(), +// _amount: amount, +// _minAmountOut: minAmountOut, +// _receiver: user +// }); + +// assertEq(usdx.balanceOf(user), 0); +// assertEq(usdc.balanceOf(user), 0); +// assertEq(susdc.balanceOf(user), received); +// assertGe(received, minAmountOut); +// assertGe(susdc.balanceOf(user), minAmountOut); + +// susdc.approve(address(zap), received); +// minAmountOut = received * 99 / 100; + +// received = zap.sell({ +// _synthId: zap.SSTATA_SPOT_ID(), +// _amount: received, +// _minAmountOut: minAmountOut, +// _receiver: user +// }); +// vm.stopPrank(); + +// assertGe(usdx.balanceOf(user), minAmountOut); +// assertGe(received, minAmountOut); +// assertEq(usdx.balanceOf(user), received); +// assertEq(susdc.balanceOf(user), 0); + +// assertEq(usdc.balanceOf(address(zap)), 0); +// assertEq(susdc.balanceOf(address(zap)), 0); +// assertEq(usdx.balanceOf(address(zap)), 0); +// } + +// function testUnwrap( /* uint32 amount */ ) +// public +// selectFork(FORK["1_zap"]) +// { +// address user = vm.addr(4); +// uint256 amount = 1000e6; +// _spin(user, usdc, amount); + +// vm.startPrank(user); +// usdc.approve(address(zap), amount); + +// uint256 wrapped = zap.wrap({ +// _token: address(usdc), +// _synthId: zap.SSTATA_SPOT_ID(), +// _amount: amount, +// _minAmountOut: amount, +// _receiver: user +// }); + +// assertEq(usdc.balanceOf(user), 0); +// assertEq(wrapped, amount * 1e12); +// assertEq(susdc.balanceOf(user), amount * 1e12); + +// susdc.approve(address(zap), type(uint256).max); + +// uint256 unwrapped = zap.unwrap({ +// _token: address(usdc), +// _synthId: zap.SSTATA_SPOT_ID(), +// _amount: wrapped, +// _minAmountOut: amount, +// _receiver: user +// }); +// vm.stopPrank(); + +// assertEq(unwrapped, amount); +// assertEq(usdc.balanceOf(user), amount); +// assertEq(susdc.balanceOf(user), 0); + +// assertEq(usdc.balanceOf(address(zap)), 0); +// assertEq(susdc.balanceOf(address(zap)), 0); +// assertEq(usdx.balanceOf(address(zap)), 0); +// } + +// function testWrap( /*uint64 amount*/ ) public selectFork(FORK["1_zap"]) { +// address user = vm.addr(6); +// uint64 amount = 1000e6; +// _spin(user, usdc, amount); + +// assertEq(usdc.balanceOf(user), amount); +// assertEq(susdc.balanceOf(user), 0); + +// vm.startPrank(user); +// usdc.approve(address(zap), amount); + +// uint256 wrapped = zap.wrap({ +// _token: address(usdc), +// _synthId: zap.SSTATA_SPOT_ID(), +// _amount: amount, +// _minAmountOut: amount, +// _receiver: user +// }); +// vm.stopPrank(); + +// assertEq(wrapped, uint256(amount) * 1e12); +// assertEq(usdc.balanceOf(user), 0); +// assertEq(susdc.balanceOf(user), wrapped); + +// assertEq(usdc.balanceOf(address(zap)), 0); +// assertEq(susdc.balanceOf(address(zap)), 0); +// assertEq(usdx.balanceOf(address(zap)), 0); +// } + +// function testZapInSuccess( /*uint64 amount*/ ) +// public +// selectFork(FORK["1_zap"]) +// { +// address user = vm.addr(7); +// uint64 amount = 1000e6; +// _spin(user, usdc, amount); + +// assertEq(usdc.balanceOf(user), amount); +// assertEq(usdx.balanceOf(user), 0); + +// vm.startPrank(user); +// usdc.approve(address(zap), amount); + +// uint256 zapped = +// zap.zapIn({_amount: amount, _minAmountOut: amount, _receiver: user}); +// vm.stopPrank(); + +// assertGe(zapped, uint256(amount) * 99e10); // amount * 1e12 * 0.99 +// assertEq(usdc.balanceOf(user), 0); +// assertEq(usdx.balanceOf(user), zapped); + +// assertEq(usdc.balanceOf(address(zap)), 0); +// assertEq(susdc.balanceOf(address(zap)), 0); +// assertEq(usdx.balanceOf(address(zap)), 0); +// } + +// function testZapOutSuccess( /*uint64 amount*/ ) +// public +// selectFork(FORK["1_zap"]) +// { +// address user = vm.addr(8); +// // vm.assume(amount > 1e12); +// uint256 amount = 250e18; +// _spin(address(this), usdc, amount / 1e12); +// usdc.approve(address(zap), amount / 1e12); +// zap.wrap({ +// _token: address(usdc), +// _synthId: zap.SSTATA_SPOT_ID(), +// _amount: amount / 1e12, +// _minAmountOut: amount / 1e12, +// _receiver: address(this) +// }); +// assertEq(usdc.balanceOf(address(this)), 0); +// assertEq(susdc.balanceOf(address(this)), amount); + +// _spin(user, usdx, amount); + +// assertEq(usdc.balanceOf(user), 0); +// assertEq(usdx.balanceOf(user), amount); + +// vm.startPrank(user); +// usdx.approve(address(zap), amount); + +// uint256 zapped = zap.zapOut({ +// _amount: amount, +// _minAmountOut: amount * 9 / 1e13, +// _receiver: user +// }); +// vm.stopPrank(); + +// assertGe(zapped * 1e12, amount * 9 / 10); +// assertEq(usdc.balanceOf(user), zapped); +// assertEq(usdx.balanceOf(user), 0); + +// assertEq(usdc.balanceOf(address(zap)), 0); +// assertEq(susdc.balanceOf(address(zap)), 0); +// assertEq(usdx.balanceOf(address(zap)), 0); +// } + +// } diff --git a/test/OdosAPITest.t.sol b/test/OdosAPITest.t.sol index 6563a23..af19426 100644 --- a/test/OdosAPITest.t.sol +++ b/test/OdosAPITest.t.sol @@ -35,25 +35,26 @@ contract OdosAPITest is Bootstrap { assertEq(assembleStatus, 200); } - function test_odos_api_arbitrum() public arbitrum { - (uint256 quoteStatus, bytes memory quoteData) = getOdosQuote( - ARBITRUM_CHAIN_ID, - ARBITRUM_WETH, - 1 ether, - ARBITRUM_USDC, - DEFAULT_PROPORTION, - DEFAULT_SLIPPAGE, - address(zap) - ); - - assertEq(quoteStatus, 200); - - string memory pathId = - abi.decode(vm.parseJson(string(quoteData), ".pathId"), (string)); - - (uint256 assembleStatus,) = odosAssemble(pathId); - - assertEq(assembleStatus, 200); - } + /// @custom:disabled no stata on arbitrum + // function test_odos_api_arbitrum() public arbitrum { + // (uint256 quoteStatus, bytes memory quoteData) = getOdosQuote( + // ARBITRUM_CHAIN_ID, + // ARBITRUM_WETH, + // 1 ether, + // ARBITRUM_USDC, + // DEFAULT_PROPORTION, + // DEFAULT_SLIPPAGE, + // address(zap) + // ); + + // assertEq(quoteStatus, 200); + + // string memory pathId = + // abi.decode(vm.parseJson(string(quoteData), ".pathId"), (string)); + + // (uint256 assembleStatus,) = odosAssemble(pathId); + + // assertEq(assembleStatus, 200); + // } } diff --git a/test/Sell.t.sol b/test/Sell.t.sol index cbbfb78..b44c4d9 100644 --- a/test/Sell.t.sol +++ b/test/Sell.t.sol @@ -38,28 +38,29 @@ contract SellTest is Bootstrap { assertEq(susdc.balanceOf(ACTOR), 0); } - function test_sell_arbitrum(uint32 amount) public arbitrum { - _spin(ACTOR, usdx, amount, address(zap)); - vm.startPrank(ACTOR); - (uint256 received,) = zap.buy({ - _synthId: zap.SUSDC_SPOT_ID(), - _amount: amount, - _minAmountOut: DEFAULT_MIN_AMOUNT_OUT, - _receiver: ACTOR - }); - assertEq(usdx.balanceOf(ACTOR), 0); - assertGe(susdc.balanceOf(ACTOR), DEFAULT_MIN_AMOUNT_OUT); - susdc.approve(address(zap), type(uint256).max); - received = zap.sell({ - _synthId: zap.SUSDC_SPOT_ID(), - _amount: received, - _minAmountOut: DEFAULT_MIN_AMOUNT_OUT, - _receiver: ACTOR - }); - vm.stopPrank(); - assertGe(received, DEFAULT_MIN_AMOUNT_OUT); - assertGe(usdx.balanceOf(ACTOR), DEFAULT_MIN_AMOUNT_OUT); - assertEq(susdc.balanceOf(ACTOR), 0); - } + /// @custom:disabled no stata on arbitrum + // function test_sell_arbitrum(uint32 amount) public arbitrum { + // _spin(ACTOR, usdx, amount, address(zap)); + // vm.startPrank(ACTOR); + // (uint256 received,) = zap.buy({ + // _synthId: zap.SUSDC_SPOT_ID(), + // _amount: amount, + // _minAmountOut: DEFAULT_MIN_AMOUNT_OUT, + // _receiver: ACTOR + // }); + // assertEq(usdx.balanceOf(ACTOR), 0); + // assertGe(susdc.balanceOf(ACTOR), DEFAULT_MIN_AMOUNT_OUT); + // susdc.approve(address(zap), type(uint256).max); + // received = zap.sell({ + // _synthId: zap.SUSDC_SPOT_ID(), + // _amount: received, + // _minAmountOut: DEFAULT_MIN_AMOUNT_OUT, + // _receiver: ACTOR + // }); + // vm.stopPrank(); + // assertGe(received, DEFAULT_MIN_AMOUNT_OUT); + // assertGe(usdx.balanceOf(ACTOR), DEFAULT_MIN_AMOUNT_OUT); + // assertEq(susdc.balanceOf(ACTOR), 0); + // } } diff --git a/test/Swap.from.t.sol b/test/Swap.from.t.sol index de7ff6a..9988979 100644 --- a/test/Swap.from.t.sol +++ b/test/Swap.from.t.sol @@ -46,63 +46,64 @@ contract SwapFromTest is BootstrapWithCurrentBlock { assertEq(weth.balanceOf(address(zap)), 0); } - function test_swap_from_weth_arbitrum() public arbitrum { - { - _spin(ACTOR, weth, DEFAULT_AMOUNT, address(zap)); - assertEq(usdc.balanceOf(ACTOR), 0); - assertEq(weth.balanceOf(ACTOR), DEFAULT_AMOUNT); - assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(weth.balanceOf(address(zap)), 0); - - pathId = getOdosQuotePathId( - ARBITRUM_CHAIN_ID, ARBITRUM_WETH, DEFAULT_AMOUNT, ARBITRUM_USDC - ); - - swapPath = getAssemblePath(pathId); - } - - vm.startPrank(ACTOR); - uint256 amountOut = zap.swapFrom({ - _from: ARBITRUM_WETH, - _path: swapPath, - _amountIn: DEFAULT_AMOUNT, - _receiver: ACTOR - }); - - assertEq(usdc.balanceOf(ACTOR), amountOut); - assertEq(weth.balanceOf(ACTOR), 0); - assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(weth.balanceOf(address(zap)), 0); - } - - function test_swap_from_tbtc_arbitrum() public arbitrum { - { - _spin(ACTOR, tbtc, DEFAULT_AMOUNT, address(zap)); - assertEq(usdc.balanceOf(ACTOR), 0); - assertEq(tbtc.balanceOf(ACTOR), DEFAULT_AMOUNT); - assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(tbtc.balanceOf(address(zap)), 0); - - pathId = getOdosQuotePathId( - ARBITRUM_CHAIN_ID, ARBITRUM_TBTC, DEFAULT_AMOUNT, ARBITRUM_USDC - ); - - swapPath = getAssemblePath(pathId); - } - - vm.startPrank(ACTOR); - uint256 amountOut = zap.swapFrom({ - _from: ARBITRUM_TBTC, - _path: swapPath, - _amountIn: DEFAULT_AMOUNT, - _receiver: ACTOR - }); - - assertEq(usdc.balanceOf(ACTOR), amountOut); - assertEq(tbtc.balanceOf(ACTOR), 0); - assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(tbtc.balanceOf(address(zap)), 0); - } + /// @custom:disabled no stata on arbitrum + // function test_swap_from_weth_arbitrum() public arbitrum { + // { + // _spin(ACTOR, weth, DEFAULT_AMOUNT, address(zap)); + // assertEq(usdc.balanceOf(ACTOR), 0); + // assertEq(weth.balanceOf(ACTOR), DEFAULT_AMOUNT); + // assertEq(usdc.balanceOf(address(zap)), 0); + // assertEq(weth.balanceOf(address(zap)), 0); + + // pathId = getOdosQuotePathId( + // ARBITRUM_CHAIN_ID, ARBITRUM_WETH, DEFAULT_AMOUNT, ARBITRUM_USDC + // ); + + // swapPath = getAssemblePath(pathId); + // } + + // vm.startPrank(ACTOR); + // uint256 amountOut = zap.swapFrom({ + // _from: ARBITRUM_WETH, + // _path: swapPath, + // _amountIn: DEFAULT_AMOUNT, + // _receiver: ACTOR + // }); + + // assertEq(usdc.balanceOf(ACTOR), amountOut); + // assertEq(weth.balanceOf(ACTOR), 0); + // assertEq(usdc.balanceOf(address(zap)), 0); + // assertEq(weth.balanceOf(address(zap)), 0); + // } + + // function test_swap_from_tbtc_arbitrum() public arbitrum { + // { + // _spin(ACTOR, tbtc, DEFAULT_AMOUNT, address(zap)); + // assertEq(usdc.balanceOf(ACTOR), 0); + // assertEq(tbtc.balanceOf(ACTOR), DEFAULT_AMOUNT); + // assertEq(usdc.balanceOf(address(zap)), 0); + // assertEq(tbtc.balanceOf(address(zap)), 0); + + // pathId = getOdosQuotePathId( + // ARBITRUM_CHAIN_ID, ARBITRUM_TBTC, DEFAULT_AMOUNT, ARBITRUM_USDC + // ); + + // swapPath = getAssemblePath(pathId); + // } + + // vm.startPrank(ACTOR); + // uint256 amountOut = zap.swapFrom({ + // _from: ARBITRUM_TBTC, + // _path: swapPath, + // _amountIn: DEFAULT_AMOUNT, + // _receiver: ACTOR + // }); + + // assertEq(usdc.balanceOf(ACTOR), amountOut); + // assertEq(tbtc.balanceOf(ACTOR), 0); + // assertEq(usdc.balanceOf(address(zap)), 0); + // assertEq(tbtc.balanceOf(address(zap)), 0); + // } function test_swap_from_tbtc_base() public base { { diff --git a/test/Unwind.t.sol b/test/Unwind.t.sol index bc83f33..01ba147 100644 --- a/test/Unwind.t.sol +++ b/test/Unwind.t.sol @@ -35,54 +35,55 @@ contract UnwindTest is Bootstrap, Errors { bytes swapPath; string pathId; - function test_unwind_is_authorized() public arbitrum { - vm.prank(ACTOR); - vm.expectRevert(NotPermitted.selector); - zap.unwind(0, 0, 0, address(0), "", /*todo*/ 0, 0, 0, address(0)); - } + /// @custom:disabled no stata on arbitrum + // function test_unwind_is_authorized() public arbitrum { + // vm.prank(ACTOR); + // vm.expectRevert(NotPermitted.selector); + // zap.unwind(0, 0, 0, address(0), "", /*todo*/ 0, 0, 0, address(0)); + // } - /// @custom:todo - function test_unwind_arbitrum() public arbitrum { - IPerpsMarket perpsMarketProxy = IPerpsMarket(zap.PERPS_MARKET()); - uint256 initialAccountDebt = perpsMarketProxy.debt(ACCOUNT_ID); - assertEq(initialAccountDebt, INITIAL_DEBT); + // /// @custom:todo + // function test_unwind_arbitrum() public arbitrum { + // IPerpsMarket perpsMarketProxy = IPerpsMarket(zap.PERPS_MARKET()); + // uint256 initialAccountDebt = perpsMarketProxy.debt(ACCOUNT_ID); + // assertEq(initialAccountDebt, INITIAL_DEBT); - int256 withdrawableMargin = - perpsMarketProxy.getWithdrawableMargin(ACCOUNT_ID); + // int256 withdrawableMargin = + // perpsMarketProxy.getWithdrawableMargin(ACCOUNT_ID); - /// While there is debt, withdrawable margin should be 0 - assertEq(withdrawableMargin, 0); + // /// While there is debt, withdrawable margin should be 0 + // assertEq(withdrawableMargin, 0); - int256 availableMargin = perpsMarketProxy.getAvailableMargin(ACCOUNT_ID); - assertGt(availableMargin, 0); + // int256 availableMargin = perpsMarketProxy.getAvailableMargin(ACCOUNT_ID); + // assertGt(availableMargin, 0); - uint256 balanceBefore = IERC20(ARBITRUM_WETH).balanceOf(DEBT_ACTOR); + // uint256 balanceBefore = IERC20(ARBITRUM_WETH).balanceOf(DEBT_ACTOR); - vm.startPrank(DEBT_ACTOR); + // vm.startPrank(DEBT_ACTOR); - pathId = getOdosQuotePathId( - ARBITRUM_CHAIN_ID, ARBITRUM_WETH, SWAP_AMOUNT, ARBITRUM_USDC - ); + // pathId = getOdosQuotePathId( + // ARBITRUM_CHAIN_ID, ARBITRUM_WETH, SWAP_AMOUNT, ARBITRUM_USDC + // ); - swapPath = getAssemblePath(pathId); + // swapPath = getAssemblePath(pathId); - zap.unwind({ - _accountId: ACCOUNT_ID, - _collateralId: 4, - _collateralAmount: 36_000_000_000_000_000, - _collateral: WETH_ADDR, - _path: swapPath, - _zapMinAmountOut: 2_222_267_000_000_000_000, - _unwrapMinAmountOut: 35_964_000_000_000_000, - _swapAmountIn: SWAP_AMOUNT, - _receiver: DEBT_ACTOR - }); + // zap.unwind({ + // _accountId: ACCOUNT_ID, + // _collateralId: 4, + // _collateralAmount: 36_000_000_000_000_000, + // _collateral: WETH_ADDR, + // _path: swapPath, + // _zapMinAmountOut: 2_222_267_000_000_000_000, + // _unwrapMinAmountOut: 35_964_000_000_000_000, + // _swapAmountIn: SWAP_AMOUNT, + // _receiver: DEBT_ACTOR + // }); - vm.stopPrank(); + // vm.stopPrank(); - uint256 balanceAfter = IERC20(ARBITRUM_WETH).balanceOf(DEBT_ACTOR); + // uint256 balanceAfter = IERC20(ARBITRUM_WETH).balanceOf(DEBT_ACTOR); - assertGt(balanceAfter, balanceBefore); - } + // assertGt(balanceAfter, balanceBefore); + // } } diff --git a/test/Unwrap.t.sol b/test/Unwrap.t.sol index 12bc838..4fa0212 100644 --- a/test/Unwrap.t.sol +++ b/test/Unwrap.t.sol @@ -40,30 +40,31 @@ contract UnwrapTest is Bootstrap { assertEq(susdc.balanceOf(ACTOR), 0); } - function test_unwrap_arbitrum(uint32 amount) public arbitrum { - _spin(ACTOR, usdc, amount, address(zap)); - vm.startPrank(ACTOR); - uint256 wrapped = zap.wrap({ - _token: address(usdc), - _synthId: zap.SUSDC_SPOT_ID(), - _amount: amount, - _minAmountOut: DEFAULT_MIN_AMOUNT_OUT, - _receiver: ACTOR - }); - assertEq(usdc.balanceOf(ACTOR), 0); - assertGe(susdc.balanceOf(ACTOR), DEFAULT_MIN_AMOUNT_OUT); - susdc.approve(address(zap), type(uint256).max); - uint256 unwrapped = zap.unwrap({ - _token: address(usdc), - _synthId: zap.SUSDC_SPOT_ID(), - _amount: wrapped, - _minAmountOut: DEFAULT_MIN_AMOUNT_OUT, - _receiver: ACTOR - }); - vm.stopPrank(); - assertGe(unwrapped, DEFAULT_MIN_AMOUNT_OUT); - assertEq(usdc.balanceOf(ACTOR), amount); - assertEq(susdc.balanceOf(ACTOR), 0); - } + /// @custom:disabled no stata on arbitrum + // function test_unwrap_arbitrum(uint32 amount) public arbitrum { + // _spin(ACTOR, usdc, amount, address(zap)); + // vm.startPrank(ACTOR); + // uint256 wrapped = zap.wrap({ + // _token: address(usdc), + // _synthId: zap.SUSDC_SPOT_ID(), + // _amount: amount, + // _minAmountOut: DEFAULT_MIN_AMOUNT_OUT, + // _receiver: ACTOR + // }); + // assertEq(usdc.balanceOf(ACTOR), 0); + // assertGe(susdc.balanceOf(ACTOR), DEFAULT_MIN_AMOUNT_OUT); + // susdc.approve(address(zap), type(uint256).max); + // uint256 unwrapped = zap.unwrap({ + // _token: address(usdc), + // _synthId: zap.SUSDC_SPOT_ID(), + // _amount: wrapped, + // _minAmountOut: DEFAULT_MIN_AMOUNT_OUT, + // _receiver: ACTOR + // }); + // vm.stopPrank(); + // assertGe(unwrapped, DEFAULT_MIN_AMOUNT_OUT); + // assertEq(usdc.balanceOf(ACTOR), amount); + // assertEq(susdc.balanceOf(ACTOR), 0); + // } } diff --git a/test/Withdraw.t.sol b/test/Withdraw.t.sol index 03e11e5..64a7647 100644 --- a/test/Withdraw.t.sol +++ b/test/Withdraw.t.sol @@ -15,11 +15,12 @@ import { contract WithdrawTest is Bootstrap, Errors { - function test_withdraw_is_authorized_arbitrum() public arbitrum { - vm.prank(ACTOR); - vm.expectRevert(NotPermitted.selector); - zap.withdraw(0, 0, 0, address(0)); - } + /// @custom:disabled no stata on arbitrum + // function test_withdraw_is_authorized_arbitrum() public arbitrum { + // vm.prank(ACTOR); + // vm.expectRevert(NotPermitted.selector); + // zap.withdraw(0, 0, 0, address(0)); + // } function test_withdraw_is_authorized_base() public base { vm.prank(ACTOR); @@ -49,26 +50,27 @@ contract WithdrawTest is Bootstrap, Errors { assertEq(usdx.balanceOf(ACTOR), amount); } - function test_withdraw_arbitrum() public arbitrum { - uint32 amount = 1_000_000_000; - _spin(ACTOR, usdx, amount, address(zap)); - vm.startPrank(ACTOR); - uint128 accountId = perpsMarket.createAccount(); - int128 margin = int128(int32(amount)); - usdx.approve(address(perpsMarket), type(uint256).max); - perpsMarket.grantPermission( - accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) - ); - perpsMarket.modifyCollateral(accountId, 0, margin); - assertEq(usdx.balanceOf(ACTOR), 0); - zap.withdraw({ - _synthId: 0, - _amount: amount, - _accountId: accountId, - _receiver: ACTOR - }); - vm.stopPrank(); - assertEq(usdx.balanceOf(ACTOR), amount); - } + /// @custom:disabled no stata on arbitrum + // function test_withdraw_arbitrum() public arbitrum { + // uint32 amount = 1_000_000_000; + // _spin(ACTOR, usdx, amount, address(zap)); + // vm.startPrank(ACTOR); + // uint128 accountId = perpsMarket.createAccount(); + // int128 margin = int128(int32(amount)); + // usdx.approve(address(perpsMarket), type(uint256).max); + // perpsMarket.grantPermission( + // accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) + // ); + // perpsMarket.modifyCollateral(accountId, 0, margin); + // assertEq(usdx.balanceOf(ACTOR), 0); + // zap.withdraw({ + // _synthId: 0, + // _amount: amount, + // _accountId: accountId, + // _receiver: ACTOR + // }); + // vm.stopPrank(); + // assertEq(usdx.balanceOf(ACTOR), amount); + // } } diff --git a/test/Wrap.t.sol b/test/Wrap.t.sol index 26eb2be..8b7d459 100644 --- a/test/Wrap.t.sol +++ b/test/Wrap.t.sol @@ -32,22 +32,23 @@ contract WrapTest is Bootstrap { assertEq(susdc.balanceOf(ACTOR), wrapped); } - function test_wrap_arbitrum(uint32 amount) public arbitrum { - _spin(ACTOR, usdc, amount, address(zap)); - assertEq(usdc.balanceOf(ACTOR), amount); - assertEq(susdc.balanceOf(ACTOR), 0); - vm.startPrank(ACTOR); - uint256 wrapped = zap.wrap({ - _token: address(usdc), - _synthId: zap.SUSDC_SPOT_ID(), - _amount: amount, - _minAmountOut: DEFAULT_MIN_AMOUNT_OUT, - _receiver: ACTOR - }); - vm.stopPrank(); - assertGe(wrapped, DEFAULT_MIN_AMOUNT_OUT); - assertEq(usdc.balanceOf(ACTOR), 0); - assertEq(susdc.balanceOf(ACTOR), wrapped); - } + /// @custom:disabled no stata on arbitrum + // function test_wrap_arbitrum(uint32 amount) public arbitrum { + // _spin(ACTOR, usdc, amount, address(zap)); + // assertEq(usdc.balanceOf(ACTOR), amount); + // assertEq(susdc.balanceOf(ACTOR), 0); + // vm.startPrank(ACTOR); + // uint256 wrapped = zap.wrap({ + // _token: address(usdc), + // _synthId: zap.SUSDC_SPOT_ID(), + // _amount: amount, + // _minAmountOut: DEFAULT_MIN_AMOUNT_OUT, + // _receiver: ACTOR + // }); + // vm.stopPrank(); + // assertGe(wrapped, DEFAULT_MIN_AMOUNT_OUT); + // assertEq(usdc.balanceOf(ACTOR), 0); + // assertEq(susdc.balanceOf(ACTOR), wrapped); + // } } From 3888c0a40c8335c8a11f0587e65cd1261b4dc73b Mon Sep 17 00:00:00 2001 From: Andrew Chiaramonte Date: Fri, 21 Feb 2025 10:30:25 -0500 Subject: [PATCH 10/24] =?UTF-8?q?=E2=9C=A8=20fmt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- script/Deploy.s.sol | 18 ++++++--- src/Zap.sol | 16 +++++++- test/Aave.t.sol | 36 ++++++++--------- test/Burn.t.sol | 3 +- test/EndToEnd.t.sol | 84 ++++++++++++++++++++++++++-------------- test/Swap.from.t.sol | 6 ++- test/Unwind.t.sol | 3 +- test/utils/Bootstrap.sol | 18 ++++++--- 8 files changed, 119 insertions(+), 65 deletions(-) diff --git a/script/Deploy.s.sol b/script/Deploy.s.sol index fa75c20..e06afb9 100644 --- a/script/Deploy.s.sol +++ b/script/Deploy.s.sol @@ -80,14 +80,17 @@ contract DeployArbitrum is Deploy, Arbitrum { Zap zap = deploySystem({ usdc: ARBITRUM_USDC, usdx: ARBITRUM_USDX, - sstata: address(0), //todo we are not deploying this stata release to arbitrum + sstata: address(0), //todo we are not deploying this stata release + // to arbitrum spotMarket: ARBITRUM_SPOT_MARKET, perpsMarket: ARBITRUM_PERPS_MARKET, referrer: ARBITRUM_REFERRER, susdcSpotId: ARBITRUM_SUSDC_SPOT_MARKET_ID, - sstataSpotId: 0, //todo we are not deploying this stata release to arbitrum + sstataSpotId: 0, //todo we are not deploying this stata release to + // arbitrum aave: ARBITRUM_AAVE_POOL, - stata: address(0), //todo we are not deploying this stata release to arbitrum + stata: address(0), //todo we are not deploying this stata release to + // arbitrum router: ARBITRUM_ROUTER }); Flush(address(zap)).nominatePlumber(ARBITRUM_PDAO); @@ -102,14 +105,17 @@ contract DeployArbitrumSepolia is Deploy, ArbitrumSepolia { Zap zap = deploySystem({ usdc: ARBITRUM_SEPOLIA_USDC, usdx: ARBITRUM_SEPOLIA_USDX, - sstata: address(0), //todo we are not deploying this stata release to arbitrum + sstata: address(0), //todo we are not deploying this stata release + // to arbitrum spotMarket: ARBITRUM_SEPOLIA_SPOT_MARKET, perpsMarket: ARBITRUM_SEPOLIA_PERPS_MARKET, referrer: ARBITRUM_SEPOLIA_REFERRER, susdcSpotId: ARBITRUM_SEPOLIA_SUSDC_SPOT_MARKET_ID, - sstataSpotId: 0, //todo we are not deploying this stata release to arbitrum + sstataSpotId: 0, //todo we are not deploying this stata release to + // arbitrum aave: ARBITRUM_SEPOLIA_AAVE_POOL, - stata: address(0), //todo we are not deploying this stata release to arbitrum + stata: address(0), //todo we are not deploying this stata release to + // arbitrum router: ARBITRUM_SEPOLIA_ROUTER }); Flush(address(zap)).nominatePlumber(ARBITRUM_SEPOLIA_PDAO); diff --git a/src/Zap.sol b/src/Zap.sol index 5169b04..f1d4019 100644 --- a/src/Zap.sol +++ b/src/Zap.sol @@ -202,7 +202,13 @@ contract Zap is Reentrancy, Errors, Flush(msg.sender) { /// @param _amount amount of STATA to deposit /// @param _receiver address to receive deposited STATA /// @return shares received - function _depositStata(uint256 _amount, address _receiver) internal returns (uint256 shares) { + function _depositStata( + uint256 _amount, + address _receiver + ) + internal + returns (uint256 shares) + { IERC20(USDC).approve(STATA, _amount); shares = IERC4626(STATA).deposit(_amount, _receiver); } @@ -211,7 +217,13 @@ contract Zap is Reentrancy, Errors, Flush(msg.sender) { /// @param _shares amount of STATA to redeem /// @param _receiver address to receive redeemed STATA /// @return assets received - function _redeemStata(uint256 _shares, address _receiver) internal returns (uint256 assets) { + function _redeemStata( + uint256 _shares, + address _receiver + ) + internal + returns (uint256 assets) + { assets = IERC4626(STATA).redeem(_shares, _receiver, _receiver); } diff --git a/test/Aave.t.sol b/test/Aave.t.sol index f3dba9f..4a3d175 100644 --- a/test/Aave.t.sol +++ b/test/Aave.t.sol @@ -14,23 +14,21 @@ import { } from "./utils/Bootstrap.sol"; contract AaveTest is Bootstrap, Errors { - - /// @custom:disabled no stata on arbitrum - // function test_executeOperation_only_aave( - // address caller, - // address a, - // uint256 b, - // uint256 c, - // bytes calldata d - // ) - // public - // arbitrum - // { - // if (caller != zap.AAVE()) { - // vm.prank(caller); - // vm.expectRevert(abi.encodeWithSelector(OnlyAave.selector, caller)); - // zap.executeOperation(a, b, c, a, d); - // } - // } - +/// @custom:disabled no stata on arbitrum +// function test_executeOperation_only_aave( +// address caller, +// address a, +// uint256 b, +// uint256 c, +// bytes calldata d +// ) +// public +// arbitrum +// { +// if (caller != zap.AAVE()) { +// vm.prank(caller); +// vm.expectRevert(abi.encodeWithSelector(OnlyAave.selector, caller)); +// zap.executeOperation(a, b, c, a, d); +// } +// } } diff --git a/test/Burn.t.sol b/test/Burn.t.sol index 7e58eba..292760a 100644 --- a/test/Burn.t.sol +++ b/test/Burn.t.sol @@ -21,7 +21,8 @@ contract BurnTest is Bootstrap { // ///@notice passes at block 269_610_923 // function test_burn_arbitrum(uint32 amount) public arbitrum { // IERC20 A_USDX = IERC20(ARBITRUM_USDX); - // uint128 accountID = 170_141_183_460_469_231_731_687_303_715_884_105_766; + // uint128 accountID = + // 170_141_183_460_469_231_731_687_303_715_884_105_766; // address accountOwner = 0x12a41a75793b6ac2cdDAF680798BB461a1024a46; diff --git a/test/EndToEnd.t.sol b/test/EndToEnd.t.sol index a581969..afe6449 100644 --- a/test/EndToEnd.t.sol +++ b/test/EndToEnd.t.sol @@ -48,7 +48,8 @@ // } // receive() external payable { -// // could call back into zap to do another swap but that just pays more +// // could call back into zap to do another swap but that just pays +// more // // fees, no real profit // // could transfer usdc into zap for zap to be able to pay back the // // original caller but that is also just shuffling your own assets @@ -72,19 +73,23 @@ // uint128 smallAccountIdNoOi = // 170_141_183_460_469_231_731_687_303_715_884_106_052; -// address smallAccountNoOiOwner = 0xbd400F9a17DC18bc031DBF5ffCD2689F4BF650dD; +// address smallAccountNoOiOwner = +// 0xbd400F9a17DC18bc031DBF5ffCD2689F4BF650dD; // uint128 smallAccountIdWithOi = // 170_141_183_460_469_231_731_687_303_715_884_106_146; -// address smallAccountWithOiOwner = 0x46232CbDB0512Ca7B00B8271e285BF8447F1330b; +// address smallAccountWithOiOwner = +// 0x46232CbDB0512Ca7B00B8271e285BF8447F1330b; // uint128 largeAccountIdNoOi = // 170_141_183_460_469_231_731_687_303_715_884_105_759; -// address largeAccountNoOiOwner = 0x626a7d9f7bBCaEB1Fa88E8128Bec8f2Dd48b2b4d; +// address largeAccountNoOiOwner = +// 0x626a7d9f7bBCaEB1Fa88E8128Bec8f2Dd48b2b4d; // uint128 largeAccountIdWithOi = // 170_141_183_460_469_231_731_687_303_715_884_105_846; -// address largeAccountWithOiOwner = 0x1C1e747A6BE850549E9655addf59FD9e7cC2D4dC; +// address largeAccountWithOiOwner = +// 0x1C1e747A6BE850549E9655addf59FD9e7cC2D4dC; // string RPC = vm.envString("ARBITRUM_RPC"); // mapping(string => uint256) FORK; @@ -111,7 +116,8 @@ // FORK["10_zap"] = vm.createFork(RPC, blockNumber_10_zap); // FORK["100_zap"] = vm.createFork(RPC, blockNumber_100_zap); -// FORK["1000_attacker"] = vm.createFork(RPC, blockNumber_1000_attacker); +// FORK["1000_attacker"] = vm.createFork(RPC, +// blockNumber_1000_attacker); // } // function initilizeFork(uint256 fork) public { @@ -172,7 +178,8 @@ // "getPriceUnsafe(bytes32)", // 0xff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace // ), -// abi.encode(314_393_291_700, 176_780_592, int32(-8), block.timestamp) +// abi.encode(314_393_291_700, 176_780_592, int32(-8), +// block.timestamp) // ); // vm.mockCall( // address(pyth), @@ -348,8 +355,10 @@ // selectFork(FORK["10_attacker"]) // { // Attacker attackerContract = new Attacker(usdc, address(zap)); -// uint256 amountUsdc = 1 ether; // non-realistic amount of USDC, but it is -// // more to prove that the reentrancy is possible but not feasible or +// uint256 amountUsdc = 1 ether; // non-realistic amount of USDC, but it +// is +// // more to prove that the reentrancy is possible but not feasible +// or // // exploitable // address attacker = vm.addr(1234); @@ -362,7 +371,8 @@ // vm.startPrank(attacker); // usdc.approve(address(zap), amountUsdc); -// zap.swapFrom(address(usdc), swapData_10_attacker, amountUsdc, attacker); +// zap.swapFrom(address(usdc), swapData_10_attacker, amountUsdc, +// attacker); // vm.stopPrank(); // uint256 ethBalAfter = address(attackerContract).balance; @@ -389,7 +399,8 @@ // uint256 tcvBefore = perpsMarket.totalCollateralValue(accountId); // uint256 debt = perpsMarket.debt(accountId); -// uint256 collateralAmount = perpsMarket.getCollateralAmount(accountId, 4); +// uint256 collateralAmount = perpsMarket.getCollateralAmount(accountId, +// 4); // uint256 wethBefore = weth.balanceOf(address(this)); // uint256 usdcBefore = usdc.balanceOf(address(this)); @@ -448,7 +459,8 @@ // uint256 tcvBefore = perpsMarket.totalCollateralValue(accountId); // uint256 debt = perpsMarket.debt(accountId); -// uint256 collateralAmount = perpsMarket.getCollateralAmount(accountId, 4); +// uint256 collateralAmount = perpsMarket.getCollateralAmount(accountId, +// 4); // uint256 wethBefore = weth.balanceOf(address(this)); // uint256 usdcBefore = usdc.balanceOf(address(this)); @@ -482,7 +494,8 @@ // assertGt( // perpsMarket.totalCollateralValue(accountId), // tcvBefore - outValue_0p01_zap -// ); // this check is weak because the oracle price on this block is diff +// ); // this check is weak because the oracle price on this block is +// diff // // from the odos api price // assertGt(perpsMarket.totalAccountOpenInterest(accountId), 0); // assertFalse( @@ -512,7 +525,8 @@ // uint256 tcvBefore = perpsMarket.totalCollateralValue(accountId); // uint256 debt = perpsMarket.debt(accountId); -// uint256 collateralAmount = perpsMarket.getCollateralAmount(accountId, 4); +// uint256 collateralAmount = perpsMarket.getCollateralAmount(accountId, +// 4); // uint256 wethBefore = weth.balanceOf(address(this)); // uint256 usdcBefore = usdc.balanceOf(address(this)); @@ -556,7 +570,8 @@ // assertEq(usdx.balanceOf(address(zap)), 0); // } -// function testUnwindSmallDebtNoOI_Overpay_AccountOwner_OdosToWrongAddress_Fail( +// function +// testUnwindSmallDebtNoOI_Overpay_AccountOwner_OdosToWrongAddress_Fail( // ) // public // selectFork(FORK["0p01_wrong"]) @@ -566,7 +581,8 @@ // uint256 tcvBefore = perpsMarket.totalCollateralValue(accountId); // uint256 debt = perpsMarket.debt(accountId); -// uint256 collateralAmount = perpsMarket.getCollateralAmount(accountId, 4); +// uint256 collateralAmount = perpsMarket.getCollateralAmount(accountId, +// 4); // uint256 wethBefore = weth.balanceOf(address(this)); // uint256 usdcBefore = usdc.balanceOf(address(this)); @@ -621,7 +637,8 @@ // uint256 tcvBefore = perpsMarket.totalCollateralValue(accountId); // uint256 debt = perpsMarket.debt(accountId); -// uint256 collateralAmount = perpsMarket.getCollateralAmount(accountId, 4); +// uint256 collateralAmount = perpsMarket.getCollateralAmount(accountId, +// 4); // uint256 wethBefore = weth.balanceOf(address(this)); // uint256 usdcBefore = usdc.balanceOf(address(this)); @@ -674,7 +691,8 @@ // uint256 tcvBefore = perpsMarket.totalCollateralValue(accountId); // uint256 debt = perpsMarket.debt(accountId); -// uint256 collateralAmount = perpsMarket.getCollateralAmount(accountId, 4); +// uint256 collateralAmount = perpsMarket.getCollateralAmount(accountId, +// 4); // uint256 wethBefore = weth.balanceOf(address(this)); // uint256 usdcBefore = usdc.balanceOf(address(this)); @@ -756,7 +774,8 @@ // uint256 tcvBefore = perpsMarket.totalCollateralValue(accountId); // uint256 debt = perpsMarket.debt(accountId); -// uint256 collateralAmount = perpsMarket.getCollateralAmount(accountId, 4); +// uint256 collateralAmount = perpsMarket.getCollateralAmount(accountId, +// 4); // uint256 wethBefore = weth.balanceOf(address(this)); // uint256 usdcBefore = usdc.balanceOf(address(this)); @@ -797,7 +816,8 @@ // ); // assertGt( // usdc.balanceOf(address(this)), -// usdcBefore + ((1000 - 2) * outAmount_10_zap / 1000) - (debt / 1e12) +// usdcBefore + ((1000 - 2) * outAmount_10_zap / 1000) - (debt / +// 1e12) // ); // assertEq(weth.balanceOf(address(zap)), 0); @@ -814,7 +834,8 @@ // uint256 tcvBefore = perpsMarket.totalCollateralValue(accountId); // uint256 debt = perpsMarket.debt(accountId); -// uint256 collateralAmount = perpsMarket.getCollateralAmount(accountId, 4); +// uint256 collateralAmount = perpsMarket.getCollateralAmount(accountId, +// 4); // uint256 wethBefore = weth.balanceOf(address(this)); // uint256 usdcBefore = usdc.balanceOf(address(this)); @@ -848,7 +869,8 @@ // assertGt( // perpsMarket.totalCollateralValue(accountId), // tcvBefore - outValue_10_zap -// ); // this check is weak because the oracle price on this block is diff +// ); // this check is weak because the oracle price on this block is +// diff // // from the odos api price // assertGt(perpsMarket.totalAccountOpenInterest(accountId), 0); // assertFalse( @@ -860,7 +882,8 @@ // assertEq(weth.balanceOf(address(this)), wethBefore); // assertGt( // usdc.balanceOf(address(this)), -// usdcBefore + ((1000 - 1) * outAmount_10_zap / 1000) - (debt / 1e12) +// usdcBefore + ((1000 - 1) * outAmount_10_zap / 1000) - (debt / +// 1e12) // ); // assertEq(weth.balanceOf(address(zap)), 0); @@ -1562,7 +1585,8 @@ // uint256 plumberWethBefore = weth.balanceOf(address(this)); // uint256 plumberUsdxBefore = usdx.balanceOf(address(this)); -// // this test contract created the Zap contract and should be the owner +// // this test contract created the Zap contract and should be the +// owner // zap.flush(address(usdx)); // assertEq(usdx.balanceOf(address(zap)), 0); @@ -1600,7 +1624,8 @@ // uint256 plumberWethBefore = weth.balanceOf(address(this)); // uint256 plumberUsdxBefore = usdx.balanceOf(address(this)); -// // this test contract created the Zap contract and should be the owner +// // this test contract created the Zap contract and should be the +// owner // vm.prank(vm.addr(987_654_321)); // vm.expectRevert(abi.encodeWithSelector(OnlyPlumber.selector)); // zap.flush(address(usdx)); @@ -1784,9 +1809,11 @@ // ); // } -// // Basic functional tests, these are similar to existing tests and were used +// // Basic functional tests, these are similar to existing tests and were +// used // // to ensure this harness worked correctly -// function testBuySuccess(uint128 amount) public selectFork(FORK["1_zap"]) { +// function testBuySuccess(uint128 amount) public selectFork(FORK["1_zap"]) +// { // // D18, fuzzing up to 3e38 // vm.assume(amount < uint128(type(int128).max / 9)); // vm.assume(amount > 10); @@ -1955,7 +1982,8 @@ // usdc.approve(address(zap), amount); // uint256 zapped = -// zap.zapIn({_amount: amount, _minAmountOut: amount, _receiver: user}); +// zap.zapIn({_amount: amount, _minAmountOut: amount, _receiver: +// user}); // vm.stopPrank(); // assertGe(zapped, uint256(amount) * 99e10); // amount * 1e12 * 0.99 diff --git a/test/Swap.from.t.sol b/test/Swap.from.t.sol index 9988979..330f606 100644 --- a/test/Swap.from.t.sol +++ b/test/Swap.from.t.sol @@ -56,7 +56,8 @@ contract SwapFromTest is BootstrapWithCurrentBlock { // assertEq(weth.balanceOf(address(zap)), 0); // pathId = getOdosQuotePathId( - // ARBITRUM_CHAIN_ID, ARBITRUM_WETH, DEFAULT_AMOUNT, ARBITRUM_USDC + // ARBITRUM_CHAIN_ID, ARBITRUM_WETH, DEFAULT_AMOUNT, + // ARBITRUM_USDC // ); // swapPath = getAssemblePath(pathId); @@ -85,7 +86,8 @@ contract SwapFromTest is BootstrapWithCurrentBlock { // assertEq(tbtc.balanceOf(address(zap)), 0); // pathId = getOdosQuotePathId( - // ARBITRUM_CHAIN_ID, ARBITRUM_TBTC, DEFAULT_AMOUNT, ARBITRUM_USDC + // ARBITRUM_CHAIN_ID, ARBITRUM_TBTC, DEFAULT_AMOUNT, + // ARBITRUM_USDC // ); // swapPath = getAssemblePath(pathId); diff --git a/test/Unwind.t.sol b/test/Unwind.t.sol index 01ba147..d57d949 100644 --- a/test/Unwind.t.sol +++ b/test/Unwind.t.sol @@ -54,7 +54,8 @@ contract UnwindTest is Bootstrap, Errors { // /// While there is debt, withdrawable margin should be 0 // assertEq(withdrawableMargin, 0); - // int256 availableMargin = perpsMarketProxy.getAvailableMargin(ACCOUNT_ID); + // int256 availableMargin = + // perpsMarketProxy.getAvailableMargin(ACCOUNT_ID); // assertGt(availableMargin, 0); // uint256 balanceBefore = IERC20(ARBITRUM_WETH).balanceOf(DEBT_ACTOR); diff --git a/test/utils/Bootstrap.sol b/test/utils/Bootstrap.sol index 76f120a..3f77109 100644 --- a/test/utils/Bootstrap.sol +++ b/test/utils/Bootstrap.sol @@ -100,14 +100,17 @@ contract Bootstrap is zap = deploySystem({ usdc: ARBITRUM_USDC, usdx: ARBITRUM_USDX, - sstata: address(0), //todo we are not deploying this stata release to arbitrum + sstata: address(0), //todo we are not deploying this stata release + // to arbitrum spotMarket: ARBITRUM_SPOT_MARKET, perpsMarket: ARBITRUM_PERPS_MARKET, referrer: ARBITRUM_REFERRER, susdcSpotId: ARBITRUM_SUSDC_SPOT_MARKET_ID, - sstataSpotId: 0, //todo we are not deploying this stata release to arbitrum + sstataSpotId: 0, //todo we are not deploying this stata release to + // arbitrum aave: ARBITRUM_AAVE_POOL, - stata: address(0), //todo we are not deploying this stata release to arbitrum + stata: address(0), //todo we are not deploying this stata release to + // arbitrum router: ARBITRUM_ROUTER }); @@ -130,14 +133,17 @@ contract Bootstrap is zap = deploySystem({ usdc: ARBITRUM_SEPOLIA_USDC, usdx: ARBITRUM_SEPOLIA_USDX, - sstata: address(0), //todo we are not deploying this stata release to arbitrum + sstata: address(0), //todo we are not deploying this stata release + // to arbitrum spotMarket: ARBITRUM_SEPOLIA_SPOT_MARKET, perpsMarket: ARBITRUM_SEPOLIA_PERPS_MARKET, referrer: ARBITRUM_SEPOLIA_REFERRER, susdcSpotId: ARBITRUM_SEPOLIA_SUSDC_SPOT_MARKET_ID, - sstataSpotId: 0, //todo we are not deploying this stata release to arbitrum + sstataSpotId: 0, //todo we are not deploying this stata release to + // arbitrum aave: ARBITRUM_SEPOLIA_AAVE_POOL, - stata: address(0), //todo we are not deploying this stata release to arbitrum + stata: address(0), //todo we are not deploying this stata release to + // arbitrum router: ARBITRUM_SEPOLIA_ROUTER }); From 6b7ad99aeae0048115287f9457f82538c3fb65e8 Mon Sep 17 00:00:00 2001 From: Moss Date: Thu, 6 Mar 2025 13:00:54 +0100 Subject: [PATCH 11/24] stata audit remediations --- src/Zap.sol | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Zap.sol b/src/Zap.sol index f1d4019..3870323 100644 --- a/src/Zap.sol +++ b/src/Zap.sol @@ -503,7 +503,8 @@ contract Zap is Reentrancy, Errors, Flush(msg.sender) { uint256 unwound = _unwind(_flashloan, _premium, _params); - if (unwound > 0) _push(_collateral, _receiver, unwound); + if (unwound > 0 && _collateral != STATA) _push(_collateral, _receiver, unwound); + else if (unwound > 0 && _collateral == STATA) _push(USDC, _receiver, unwound); return IERC20(USDC).approve(AAVE, _flashloan + _premium); } @@ -582,7 +583,7 @@ contract Zap is Reentrancy, Errors, Flush(msg.sender) { // i.e., USDe -(swap)-> USDC -(repay)-> Aave // i.e., USDC -(repay)-> Aave // whatever collateral amount is remaining is returned to the caller - if (_collateral == USDC) { + if (_collateral == USDC || _collateral == STATA) { unwound -= _flashloan; } else { odosSwap(_collateral, _swapAmountIn, _path); From 30168b30000138a2b8c4c633abef58a1dfd30b14 Mon Sep 17 00:00:00 2001 From: Moss Date: Thu, 6 Mar 2025 13:09:24 +0100 Subject: [PATCH 12/24] fmt --- src/Zap.sol | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Zap.sol b/src/Zap.sol index 3870323..3549cc6 100644 --- a/src/Zap.sol +++ b/src/Zap.sol @@ -503,8 +503,11 @@ contract Zap is Reentrancy, Errors, Flush(msg.sender) { uint256 unwound = _unwind(_flashloan, _premium, _params); - if (unwound > 0 && _collateral != STATA) _push(_collateral, _receiver, unwound); - else if (unwound > 0 && _collateral == STATA) _push(USDC, _receiver, unwound); + if (unwound > 0 && _collateral != STATA) { + _push(_collateral, _receiver, unwound); + } else if (unwound > 0 && _collateral == STATA) { + _push(USDC, _receiver, unwound); + } return IERC20(USDC).approve(AAVE, _flashloan + _premium); } From 276f62b706dc6d3fa25aaceb6b18602e00d8fbac Mon Sep 17 00:00:00 2001 From: Moss Date: Thu, 6 Mar 2025 14:15:41 +0100 Subject: [PATCH 13/24] removed all references to arbitrum and replaced with base --- .env-example | 5 +- README.md | 6 +- foundry.toml | 2 - makefile | 3 - script/Deploy.s.sol | 58 ++++---------- script/utils/Parameters.sol | 45 +++-------- test/Aave.t.sol | 4 +- test/Burn.t.sol | 10 +-- test/Buy.t.sol | 5 +- test/EndToEnd.t.sol | 35 ++++----- test/Flush.t.sol | 2 +- test/OdosAPITest.t.sol | 10 +-- test/Sell.t.sol | 5 +- test/Swap.from.t.sol | 18 ++--- test/Unwind.t.sol | 12 +-- test/Unwrap.t.sol | 4 +- test/Withdraw.t.sol | 8 +- test/Wrap.t.sol | 4 +- test/Zap.in.t.sol | 4 +- test/Zap.out.t.sol | 4 +- test/utils/Bootstrap.sol | 96 ++++++++++++------------ test/utils/BootstrapWithCurrentBlock.sol | 10 +-- test/utils/Constants.sol | 16 ++-- 23 files changed, 153 insertions(+), 213 deletions(-) diff --git a/.env-example b/.env-example index f143e60..5fda35c 100644 --- a/.env-example +++ b/.env-example @@ -1,7 +1,4 @@ BASE_RPC=https://base-mainnet.g.alchemy.com/v2/ -ARBITRUM_RPC=https://arb-mainnet.g.alchemy.com/v2/ -ARBITRUM_SEPOLIA_RPC=https://arb-sepolia.g.alchemy.com/v2/ +BASE_SEPOLIA_RPC=https://base-sepolia.g.alchemy.com/v2/ BASESCAN_API_KEY= -ARBISCAN_API_KEY= -ARBISCAN_SEPOLIA_API_KEY= PRIVATE_KEY= \ No newline at end of file diff --git a/README.md b/README.md index 278e995..d6e5b6d 100644 --- a/README.md +++ b/README.md @@ -72,7 +72,7 @@ USDC <--(spot market)--> sUSDC <--(spot market)--> USDx ## How to Deploy -- See the `deployments/` folder for Arbitrum and Base deployments. +- See the `deployments/` folder for Base deployments. How to Deploy: @@ -82,10 +82,6 @@ How to Deploy: ``` make deploy_base ``` -3. Deploy to Arbitrum - ``` - make deploy_arbitrum - ``` ## Audits diff --git a/foundry.toml b/foundry.toml index 06604a9..9fb0fb2 100644 --- a/foundry.toml +++ b/foundry.toml @@ -20,9 +20,7 @@ override_spacing = false wrap_comments = true [rpc_endpoints] -arbitrum = "${ARBITRUM_RPC}" base = "${BASE_RPC}" [etherscan] -arbitrum = { key = "${ARBISCAN_API_KEY}" } base = { key = "${BASESCAN_API_KEY}" } \ No newline at end of file diff --git a/makefile b/makefile index 602be6d..e729cd6 100644 --- a/makefile +++ b/makefile @@ -1,9 +1,6 @@ deploy_base: source .env && forge script --chain base script/Deploy.s.sol:DeployBase --rpc-url $$BASE_RPC --broadcast --verify -vvvv -deploy_arbitrum: - source .env && forge script --chain arbitrum script/Deploy.s.sol:DeployArbitrum --rpc-url $$ARBITRUM_RPC --broadcast --verify -vvvv - coverage: forge coverage --report lcov --ir-minimum diff --git a/script/Deploy.s.sol b/script/Deploy.s.sol index e06afb9..125fa8c 100644 --- a/script/Deploy.s.sol +++ b/script/Deploy.s.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.27; import {Script} from "../lib/forge-std/src/Script.sol"; import {Flush, Zap} from "../src/Zap.sol"; -import {Arbitrum, ArbitrumSepolia, Base} from "./utils/Parameters.sol"; +import {BaseSepolia, Base} from "./utils/Parameters.sol"; /// @title zap deployment script /// @author @jaredborders @@ -73,52 +73,24 @@ contract DeployBase is Deploy, Base { } -/// @custom:deplo `make deploy_arbitrum` -contract DeployArbitrum is Deploy, Arbitrum { +/// @custom:deploy `make deploy_basesepolia` +contract DeployBaseSepolia is Deploy, BaseSepolia { function run() public broadcast { Zap zap = deploySystem({ - usdc: ARBITRUM_USDC, - usdx: ARBITRUM_USDX, - sstata: address(0), //todo we are not deploying this stata release - // to arbitrum - spotMarket: ARBITRUM_SPOT_MARKET, - perpsMarket: ARBITRUM_PERPS_MARKET, - referrer: ARBITRUM_REFERRER, - susdcSpotId: ARBITRUM_SUSDC_SPOT_MARKET_ID, - sstataSpotId: 0, //todo we are not deploying this stata release to - // arbitrum - aave: ARBITRUM_AAVE_POOL, - stata: address(0), //todo we are not deploying this stata release to - // arbitrum - router: ARBITRUM_ROUTER + usdc: base_SEPOLIA_USDC, + usdx: base_SEPOLIA_USDX, + sstata: address(0), //todo we are not deploying this stata release to base + spotMarket: base_SEPOLIA_SPOT_MARKET, + perpsMarket: base_SEPOLIA_PERPS_MARKET, + referrer: base_SEPOLIA_REFERRER, + susdcSpotId: base_SEPOLIA_SUSDC_SPOT_MARKET_ID, + sstataSpotId: 0, //todo we are not deploying this stata release to base + aave: base_SEPOLIA_AAVE_POOL, + stata: address(0), //todo we are not deploying this stata release to base + router: base_SEPOLIA_ROUTER }); - Flush(address(zap)).nominatePlumber(ARBITRUM_PDAO); - } - -} - -/// @custom:deploy `make deploy_arbitrum_sepolia` -contract DeployArbitrumSepolia is Deploy, ArbitrumSepolia { - - function run() public broadcast { - Zap zap = deploySystem({ - usdc: ARBITRUM_SEPOLIA_USDC, - usdx: ARBITRUM_SEPOLIA_USDX, - sstata: address(0), //todo we are not deploying this stata release - // to arbitrum - spotMarket: ARBITRUM_SEPOLIA_SPOT_MARKET, - perpsMarket: ARBITRUM_SEPOLIA_PERPS_MARKET, - referrer: ARBITRUM_SEPOLIA_REFERRER, - susdcSpotId: ARBITRUM_SEPOLIA_SUSDC_SPOT_MARKET_ID, - sstataSpotId: 0, //todo we are not deploying this stata release to - // arbitrum - aave: ARBITRUM_SEPOLIA_AAVE_POOL, - stata: address(0), //todo we are not deploying this stata release to - // arbitrum - router: ARBITRUM_SEPOLIA_ROUTER - }); - Flush(address(zap)).nominatePlumber(ARBITRUM_SEPOLIA_PDAO); + Flush(address(zap)).nominatePlumber(base_SEPOLIA_PDAO); } } diff --git a/script/utils/Parameters.sol b/script/utils/Parameters.sol index 27e9ff1..8d956ca 100644 --- a/script/utils/Parameters.sol +++ b/script/utils/Parameters.sol @@ -25,47 +25,24 @@ contract Base { } -contract Arbitrum { +//TODO: add addresses +contract BaseSepolia { /// @custom:pdao - address ARBITRUM_PDAO = 0xD3DFa13CDc7c133b1700c243f03A8C6Df513A93b; + address BASE_SEPOLIA_PDAO = address(0); /// @custom:synthetix - address ARBITRUM_USDC = 0xaf88d065e77c8cC2239327C5EDb3A432268e5831; - address ARBITRUM_USDX = 0xb2F30A7C980f052f02563fb518dcc39e6bf38175; - address ARBITRUM_SPOT_MARKET = 0xa65538A6B9A8442854dEcB6E3F85782C60757D60; - address ARBITRUM_PERPS_MARKET = 0xd762960c31210Cf1bDf75b06A5192d395EEDC659; - address ARBITRUM_REFERRER = address(0); - uint128 ARBITRUM_SUSDC_SPOT_MARKET_ID = 2; + address BASE_SEPOLIA_USDC = 0x0; + address BASE_SEPOLIA_USDX = 0x0; + address BASE_SEPOLIA_SPOT_MARKET = 0x0; + address BASE_SEPOLIA_PERPS_MARKET = 0x0; + address BASE_SEPOLIA_REFERRER = address(0); + uint128 BASE_SEPOLIA_SUSDC_SPOT_MARKET_ID = 0; /// @custom:aave - address ARBITRUM_AAVE_POOL = 0x794a61358D6845594F94dc1DB02A252b5b4814aD; + address BASE_SEPOLIA_AAVE_POOL = 0x0; /// @custom:odos - address ARBITRUM_ROUTER = 0xa669e7A0d4b3e4Fa48af2dE86BD4CD7126Be4e13; - -} - -contract ArbitrumSepolia { - - /// @custom:pdao - address ARBITRUM_SEPOLIA_PDAO = address(0); - - /// @custom:synthetix - address ARBITRUM_SEPOLIA_USDC = 0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d; - address ARBITRUM_SEPOLIA_USDX = 0xe487Ad4291019b33e2230F8E2FB1fb6490325260; - address ARBITRUM_SEPOLIA_SPOT_MARKET = - 0x93d645c42A0CA3e08E9552367B8c454765fff041; - address ARBITRUM_SEPOLIA_PERPS_MARKET = - 0xA73A7B754Ec870b3738D0654cA75b7d0eEbdb460; - address ARBITRUM_SEPOLIA_REFERRER = address(0); - uint128 ARBITRUM_SEPOLIA_SUSDC_SPOT_MARKET_ID = 2; - - /// @custom:aave - address ARBITRUM_SEPOLIA_AAVE_POOL = - 0xBfC91D59fdAA134A4ED45f7B584cAf96D7792Eff; - - /// @custom:odos - address ARBITRUM_SEPOLIA_ROUTER = address(0); + address BASE_SEPOLIA_ROUTER = address(0); } diff --git a/test/Aave.t.sol b/test/Aave.t.sol index 4a3d175..d1f2a61 100644 --- a/test/Aave.t.sol +++ b/test/Aave.t.sol @@ -14,7 +14,7 @@ import { } from "./utils/Bootstrap.sol"; contract AaveTest is Bootstrap, Errors { -/// @custom:disabled no stata on arbitrum +/// @custom:disabled no stata on base? TODO: check if there is stata on base and add this test back if there is // function test_executeOperation_only_aave( // address caller, // address a, @@ -23,7 +23,7 @@ contract AaveTest is Bootstrap, Errors { // bytes calldata d // ) // public -// arbitrum +// base // { // if (caller != zap.AAVE()) { // vm.prank(caller); diff --git a/test/Burn.t.sol b/test/Burn.t.sol index 292760a..4e8dabf 100644 --- a/test/Burn.t.sol +++ b/test/Burn.t.sol @@ -16,11 +16,11 @@ import "forge-std/console2.sol"; contract BurnTest is Bootstrap { - /// @custom:disabled no stata on arbitrum + /// @custom:disabled no stata on base? TODO: add back if there is stata on base // /// @custom:todo // ///@notice passes at block 269_610_923 - // function test_burn_arbitrum(uint32 amount) public arbitrum { - // IERC20 A_USDX = IERC20(ARBITRUM_USDX); + // function test_burn_base(uint32 amount) public base { + // IERC20 A_USDX = IERC20(Base_USDX); // uint128 accountID = // 170_141_183_460_469_231_731_687_303_715_884_105_766; @@ -48,9 +48,9 @@ contract BurnTest is Bootstrap { function test_burn_base(uint32 amount) public base {} /// @custom:todo - function test_burn_arbitrum_sepolia(uint32 amount) + function test_burn_base_sepolia(uint32 amount) public - arbitrum_sepolia + base_sepolia {} } diff --git a/test/Buy.t.sol b/test/Buy.t.sol index 05e0fb2..0fcec6d 100644 --- a/test/Buy.t.sol +++ b/test/Buy.t.sol @@ -32,8 +32,9 @@ contract BuyTest is Bootstrap { assertGe(susdc.balanceOf(ACTOR), DEFAULT_MIN_AMOUNT_OUT); } - /// @custom:disabled no stata on arbitrum - // function test_buy_arbitrum(uint32 amount) public arbitrum { + /// TODO: add back test for base + /// @custom:disabled no stata on base? + // function test_buy_base(uint32 amount) public base { // _spin(ACTOR, usdx, amount, address(zap)); // assertEq(usdx.balanceOf(ACTOR), amount); // assertEq(susdc.balanceOf(ACTOR), 0); diff --git a/test/EndToEnd.t.sol b/test/EndToEnd.t.sol index afe6449..7a80459 100644 --- a/test/EndToEnd.t.sol +++ b/test/EndToEnd.t.sol @@ -1,9 +1,10 @@ -/// @custom:disabled no stata on arbitrum +/// TODO add back this test +/// @custom:disabled no stata on base? // // SPDX-License-Identifier: MIT // pragma solidity 0.8.27; -// import {Arbitrum} from "../script/utils/Parameters.sol"; +// import {Base} from "../script/utils/Parameters.sol"; // import {IERC20, Zap} from "../src/Zap.sol"; // import {Flush} from "../src/utils/Flush.sol"; // import "./interfaces/ISynthetix.sol"; @@ -59,7 +60,7 @@ // } -// contract EndToEndTest is Test, Arbitrum, Constants, OdosSwapData { +// contract EndToEndTest is Test, Base, Constants, OdosSwapData { // Zap zap; @@ -91,7 +92,7 @@ // address largeAccountWithOiOwner = // 0x1C1e747A6BE850549E9655addf59FD9e7cC2D4dC; -// string RPC = vm.envString("ARBITRUM_RPC"); +// string RPC = vm.envString("BASE_RPC"); // mapping(string => uint256) FORK; // modifier selectFork(uint256 fork) { @@ -123,14 +124,14 @@ // function initilizeFork(uint256 fork) public { // vm.selectFork(fork); -// spotMarket = ISpotMarket(ARBITRUM_SPOT_MARKET); -// perpsMarket = IPerpsMarket(ARBITRUM_PERPS_MARKET); +// spotMarket = ISpotMarket(BASE_SPOT_MARKET); +// perpsMarket = IPerpsMarket(BASE_PERPS_MARKET); -// usdc = IERC20(ARBITRUM_USDC); -// usdx = IERC20(ARBITRUM_USDX); -// weth = IERC20(ARBITRUM_WETH); +// usdc = IERC20(BASE_USDC); +// usdx = IERC20(BASE_USDX); +// weth = IERC20(BASE_WETH); -// uint128 synthMarketId = ARBITRUM_SUSDC_SPOT_MARKET_ID; +// uint128 synthMarketId = BASE_SUSDC_SPOT_MARKET_ID; // susdc = IERC20(spotMarket.getSynth(synthMarketId)); @@ -138,15 +139,15 @@ // zap = new Zap({ // _usdc: address(usdc), // _usdx: address(usdx), -// _sstata: address(0), // no stata on arbitrum +// _sstata: address(0), // no stata on base // _spotMarket: address(spotMarket), // _perpsMarket: address(perpsMarket), -// _referrer: ARBITRUM_REFERRER, +// _referrer: BASE_REFERRER, // _susdcSpotId: synthMarketId, -// _sstataSpotId: 0, // no stata on arbitrum -// _aave: ARBITRUM_AAVE_POOL, -// _stata: address(0), // no stata on arbitrum -// _router: ARBITRUM_ROUTER +// _sstataSpotId: 0, // no stata on base +// _aave: BASE_AAVE_POOL, +// _stata: address(0), // no stata on base +// _router: BASE_ROUTER // }); // IPyth pyth = IPyth(0xd74CdD8Eef0E97a5a7678F907991316f88E7965A); @@ -757,7 +758,7 @@ // public // selectFork(FORK["0p01_zap"]) // { -// vm.startPrank(ARBITRUM_AAVE_POOL); +// vm.startPrank(BASE_AAVE_POOL); // vm.expectRevert( // abi.encodeWithSelector(ReentrancyDetected.selector, 0, 1) // ); diff --git a/test/Flush.t.sol b/test/Flush.t.sol index 37b5d08..215460f 100644 --- a/test/Flush.t.sol +++ b/test/Flush.t.sol @@ -15,6 +15,6 @@ import { contract FlushTest is Bootstrap { /// @custom:todo - function test_flush(uint32 amount) public arbitrum_sepolia {} + function test_flush(uint32 amount) public base_sepolia {} } diff --git a/test/OdosAPITest.t.sol b/test/OdosAPITest.t.sol index af19426..c111777 100644 --- a/test/OdosAPITest.t.sol +++ b/test/OdosAPITest.t.sol @@ -35,13 +35,13 @@ contract OdosAPITest is Bootstrap { assertEq(assembleStatus, 200); } - /// @custom:disabled no stata on arbitrum - // function test_odos_api_arbitrum() public arbitrum { + /// @custom:disabled no stata on base + // function test_odos_api_base() public base { // (uint256 quoteStatus, bytes memory quoteData) = getOdosQuote( - // ARBITRUM_CHAIN_ID, - // ARBITRUM_WETH, + // BASE_CHAIN_ID, + // BASE_WETH, // 1 ether, - // ARBITRUM_USDC, + // BASE_USDC, // DEFAULT_PROPORTION, // DEFAULT_SLIPPAGE, // address(zap) diff --git a/test/Sell.t.sol b/test/Sell.t.sol index b44c4d9..a4e7710 100644 --- a/test/Sell.t.sol +++ b/test/Sell.t.sol @@ -38,8 +38,9 @@ contract SellTest is Bootstrap { assertEq(susdc.balanceOf(ACTOR), 0); } - /// @custom:disabled no stata on arbitrum - // function test_sell_arbitrum(uint32 amount) public arbitrum { + ///TODO: add this test back + /// @custom:disabled no stata on base + // function test_sell_base(uint32 amount) public base { // _spin(ACTOR, usdx, amount, address(zap)); // vm.startPrank(ACTOR); // (uint256 received,) = zap.buy({ diff --git a/test/Swap.from.t.sol b/test/Swap.from.t.sol index 330f606..10a532f 100644 --- a/test/Swap.from.t.sol +++ b/test/Swap.from.t.sol @@ -46,8 +46,8 @@ contract SwapFromTest is BootstrapWithCurrentBlock { assertEq(weth.balanceOf(address(zap)), 0); } - /// @custom:disabled no stata on arbitrum - // function test_swap_from_weth_arbitrum() public arbitrum { + /// @custom:disabled no stata on base + // function test_swap_from_weth_base() public base { // { // _spin(ACTOR, weth, DEFAULT_AMOUNT, address(zap)); // assertEq(usdc.balanceOf(ACTOR), 0); @@ -56,8 +56,8 @@ contract SwapFromTest is BootstrapWithCurrentBlock { // assertEq(weth.balanceOf(address(zap)), 0); // pathId = getOdosQuotePathId( - // ARBITRUM_CHAIN_ID, ARBITRUM_WETH, DEFAULT_AMOUNT, - // ARBITRUM_USDC + // BASE_CHAIN_ID, BASE_WETH, DEFAULT_AMOUNT, + // BASE_USDC // ); // swapPath = getAssemblePath(pathId); @@ -65,7 +65,7 @@ contract SwapFromTest is BootstrapWithCurrentBlock { // vm.startPrank(ACTOR); // uint256 amountOut = zap.swapFrom({ - // _from: ARBITRUM_WETH, + // _from: BASE_WETH, // _path: swapPath, // _amountIn: DEFAULT_AMOUNT, // _receiver: ACTOR @@ -77,7 +77,7 @@ contract SwapFromTest is BootstrapWithCurrentBlock { // assertEq(weth.balanceOf(address(zap)), 0); // } - // function test_swap_from_tbtc_arbitrum() public arbitrum { + // function test_swap_from_tbtc_base() public base { // { // _spin(ACTOR, tbtc, DEFAULT_AMOUNT, address(zap)); // assertEq(usdc.balanceOf(ACTOR), 0); @@ -86,8 +86,8 @@ contract SwapFromTest is BootstrapWithCurrentBlock { // assertEq(tbtc.balanceOf(address(zap)), 0); // pathId = getOdosQuotePathId( - // ARBITRUM_CHAIN_ID, ARBITRUM_TBTC, DEFAULT_AMOUNT, - // ARBITRUM_USDC + // BASE_CHAIN_ID, BASE_TBTC, DEFAULT_AMOUNT, + // BASE_USDC // ); // swapPath = getAssemblePath(pathId); @@ -95,7 +95,7 @@ contract SwapFromTest is BootstrapWithCurrentBlock { // vm.startPrank(ACTOR); // uint256 amountOut = zap.swapFrom({ - // _from: ARBITRUM_TBTC, + // _from: BASE_TBTC, // _path: swapPath, // _amountIn: DEFAULT_AMOUNT, // _receiver: ACTOR diff --git a/test/Unwind.t.sol b/test/Unwind.t.sol index d57d949..7b8234e 100644 --- a/test/Unwind.t.sol +++ b/test/Unwind.t.sol @@ -35,15 +35,15 @@ contract UnwindTest is Bootstrap, Errors { bytes swapPath; string pathId; - /// @custom:disabled no stata on arbitrum - // function test_unwind_is_authorized() public arbitrum { + /// @custom:disabled no stata on base + // function test_unwind_is_authorized() public base { // vm.prank(ACTOR); // vm.expectRevert(NotPermitted.selector); // zap.unwind(0, 0, 0, address(0), "", /*todo*/ 0, 0, 0, address(0)); // } // /// @custom:todo - // function test_unwind_arbitrum() public arbitrum { + // function test_unwind_base() public base { // IPerpsMarket perpsMarketProxy = IPerpsMarket(zap.PERPS_MARKET()); // uint256 initialAccountDebt = perpsMarketProxy.debt(ACCOUNT_ID); // assertEq(initialAccountDebt, INITIAL_DEBT); @@ -58,12 +58,12 @@ contract UnwindTest is Bootstrap, Errors { // perpsMarketProxy.getAvailableMargin(ACCOUNT_ID); // assertGt(availableMargin, 0); - // uint256 balanceBefore = IERC20(ARBITRUM_WETH).balanceOf(DEBT_ACTOR); + // uint256 balanceBefore = IERC20(BASE_WETH).balanceOf(DEBT_ACTOR); // vm.startPrank(DEBT_ACTOR); // pathId = getOdosQuotePathId( - // ARBITRUM_CHAIN_ID, ARBITRUM_WETH, SWAP_AMOUNT, ARBITRUM_USDC + // BASE_CHAIN_ID, BASE_WETH, SWAP_AMOUNT, BASE_USDC // ); // swapPath = getAssemblePath(pathId); @@ -82,7 +82,7 @@ contract UnwindTest is Bootstrap, Errors { // vm.stopPrank(); - // uint256 balanceAfter = IERC20(ARBITRUM_WETH).balanceOf(DEBT_ACTOR); + // uint256 balanceAfter = IERC20(BASE_WETH).balanceOf(DEBT_ACTOR); // assertGt(balanceAfter, balanceBefore); // } diff --git a/test/Unwrap.t.sol b/test/Unwrap.t.sol index 4fa0212..e20b0e7 100644 --- a/test/Unwrap.t.sol +++ b/test/Unwrap.t.sol @@ -40,8 +40,8 @@ contract UnwrapTest is Bootstrap { assertEq(susdc.balanceOf(ACTOR), 0); } - /// @custom:disabled no stata on arbitrum - // function test_unwrap_arbitrum(uint32 amount) public arbitrum { + /// @custom:disabled no stata on base + // function test_unwrap_base(uint32 amount) public base { // _spin(ACTOR, usdc, amount, address(zap)); // vm.startPrank(ACTOR); // uint256 wrapped = zap.wrap({ diff --git a/test/Withdraw.t.sol b/test/Withdraw.t.sol index 64a7647..a99d6ff 100644 --- a/test/Withdraw.t.sol +++ b/test/Withdraw.t.sol @@ -15,8 +15,8 @@ import { contract WithdrawTest is Bootstrap, Errors { - /// @custom:disabled no stata on arbitrum - // function test_withdraw_is_authorized_arbitrum() public arbitrum { + /// @custom:disabled no stata on base + // function test_withdraw_is_authorized_base() public base { // vm.prank(ACTOR); // vm.expectRevert(NotPermitted.selector); // zap.withdraw(0, 0, 0, address(0)); @@ -50,8 +50,8 @@ contract WithdrawTest is Bootstrap, Errors { assertEq(usdx.balanceOf(ACTOR), amount); } - /// @custom:disabled no stata on arbitrum - // function test_withdraw_arbitrum() public arbitrum { + /// @custom:disabled no stata on base + // function test_withdraw_base() public base { // uint32 amount = 1_000_000_000; // _spin(ACTOR, usdx, amount, address(zap)); // vm.startPrank(ACTOR); diff --git a/test/Wrap.t.sol b/test/Wrap.t.sol index 8b7d459..cc332dd 100644 --- a/test/Wrap.t.sol +++ b/test/Wrap.t.sol @@ -32,8 +32,8 @@ contract WrapTest is Bootstrap { assertEq(susdc.balanceOf(ACTOR), wrapped); } - /// @custom:disabled no stata on arbitrum - // function test_wrap_arbitrum(uint32 amount) public arbitrum { + /// @custom:disabled no stata on base + // function test_wrap_base(uint32 amount) public base { // _spin(ACTOR, usdc, amount, address(zap)); // assertEq(usdc.balanceOf(ACTOR), amount); // assertEq(susdc.balanceOf(ACTOR), 0); diff --git a/test/Zap.in.t.sol b/test/Zap.in.t.sol index 97bf065..d598129 100644 --- a/test/Zap.in.t.sol +++ b/test/Zap.in.t.sol @@ -29,8 +29,8 @@ contract ZapInTest is Bootstrap { assertEq(sstata.balanceOf(ACTOR), zapped); } - /// @custom:disabled no stata on arbitrum - // function test_zap_in_arbitrum(uint32 amount) public arbitrum { + /// @custom:disabled no stata on base + // function test_zap_in_base(uint32 amount) public base { // _spin(ACTOR, usdc, amount, address(zap)); // assertEq(usdc.balanceOf(ACTOR), amount); // assertEq(usdx.balanceOf(ACTOR), 0); diff --git a/test/Zap.out.t.sol b/test/Zap.out.t.sol index 9a10591..378e257 100644 --- a/test/Zap.out.t.sol +++ b/test/Zap.out.t.sol @@ -41,8 +41,8 @@ contract ZapOutTest is Bootstrap { assertEq(sstata.balanceOf(ACTOR), 0); } - /// @custom:disabled no stata on arbitrum - // function test_zap_out_arbitum(uint64 amount) public arbitrum { + /// @custom:disabled no stata on base + // function test_zap_out_base(uint64 amount) public base { // vm.assume(amount > 1e18); // _spin(ACTOR, usdx, amount, address(zap)); // assertEq(usdc.balanceOf(ACTOR), 0); diff --git a/test/utils/Bootstrap.sol b/test/utils/Bootstrap.sol index 3f77109..64c2a28 100644 --- a/test/utils/Bootstrap.sol +++ b/test/utils/Bootstrap.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.27; import {Deploy} from "../../script/Deploy.s.sol"; import { - Arbitrum, ArbitrumSepolia, Base + Base, BaseSepolia, Base } from "../../script/utils/Parameters.sol"; import {Errors, IERC20, IPool, Reentrancy, Zap} from "../../src/Zap.sol"; import {IPerpsMarket, ISpotMarket} from "../interfaces/ISynthetix.sol"; @@ -18,8 +18,8 @@ contract Bootstrap is Test, Deploy, Base, - Arbitrum, - ArbitrumSepolia, + Base, + BaseSepolia, Constants { @@ -28,8 +28,8 @@ contract Bootstrap is /// @custom:forks uint256 BASE; - uint256 ARBITRUM; - uint256 ARBITRUM_SEPOLIA; + uint256 BASE; + uint256 BASE_SEPOLIA; /// @custom:target Zap zap; @@ -48,14 +48,14 @@ contract Bootstrap is function setUp() public virtual { string memory BASE_RPC = vm.envString(BASE_RPC_REF); - string memory ARBITRUM_RPC = vm.envString(ARBITRUM_RPC_REF); - string memory ARBITRUM_SEPOLIA_RPC = - vm.envString(ARBITRUM_SEPOLIA_RPC_REF); + string memory BASE_RPC = vm.envString(BASE_RPC_REF); + string memory BASE_SEPOLIA_RPC = + vm.envString(BASE_SEPOLIA_RPC_REF); BASE = vm.createFork(BASE_RPC, BASE_FORK_BLOCK); - ARBITRUM = vm.createFork(ARBITRUM_RPC, ARBITRUM_FORK_BLOCK); - ARBITRUM_SEPOLIA = - vm.createFork(ARBITRUM_SEPOLIA_RPC, ARBITRUM_SEPOLIA_FORK_BLOCK); + BASE = vm.createFork(BASE_RPC, BASE_FORK_BLOCK); + BASE_SEPOLIA = + vm.createFork(BASE_SEPOLIA_RPC, BASE_SEPOLIA_FORK_BLOCK); headers.push("Content-Type: application/json"); } @@ -92,68 +92,68 @@ contract Bootstrap is _; } - modifier arbitrum() { + modifier base() { /// @custom:fork - vm.selectFork(ARBITRUM); + vm.selectFork(BASE); /// @custom:target zap = deploySystem({ - usdc: ARBITRUM_USDC, - usdx: ARBITRUM_USDX, + usdc: BASE_USDC, + usdx: BASE_USDX, sstata: address(0), //todo we are not deploying this stata release - // to arbitrum - spotMarket: ARBITRUM_SPOT_MARKET, - perpsMarket: ARBITRUM_PERPS_MARKET, - referrer: ARBITRUM_REFERRER, - susdcSpotId: ARBITRUM_SUSDC_SPOT_MARKET_ID, + // to base + spotMarket: BASE_SPOT_MARKET, + perpsMarket: BASE_PERPS_MARKET, + referrer: BASE_REFERRER, + susdcSpotId: BASE_SUSDC_SPOT_MARKET_ID, sstataSpotId: 0, //todo we are not deploying this stata release to - // arbitrum - aave: ARBITRUM_AAVE_POOL, + // base + aave: BASE_AAVE_POOL, stata: address(0), //todo we are not deploying this stata release to - // arbitrum - router: ARBITRUM_ROUTER + // base + router: BASE_ROUTER }); /// @custom:auxiliary - spotMarket = ISpotMarket(ARBITRUM_SPOT_MARKET); - perpsMarket = IPerpsMarket(ARBITRUM_PERPS_MARKET); - usdc = IERC20(ARBITRUM_USDC); + spotMarket = ISpotMarket(BASE_SPOT_MARKET); + perpsMarket = IPerpsMarket(BASE_PERPS_MARKET); + usdc = IERC20(BASE_USDC); susdc = IERC20(spotMarket.getSynth(zap.SSTATA_SPOT_ID())); - usdx = IERC20(ARBITRUM_USDX); - weth = IERC20(ARBITRUM_WETH); - tbtc = IERC20(ARBITRUM_TBTC); + usdx = IERC20(BASE_USDX); + weth = IERC20(BASE_WETH); + tbtc = IERC20(BASE_TBTC); _; } - modifier arbitrum_sepolia() { + modifier base_sepolia() { /// @custom:fork - vm.selectFork(ARBITRUM_SEPOLIA); + vm.selectFork(BASE_SEPOLIA); /// @custom:target zap = deploySystem({ - usdc: ARBITRUM_SEPOLIA_USDC, - usdx: ARBITRUM_SEPOLIA_USDX, + usdc: BASE_SEPOLIA_USDC, + usdx: BASE_SEPOLIA_USDX, sstata: address(0), //todo we are not deploying this stata release - // to arbitrum - spotMarket: ARBITRUM_SEPOLIA_SPOT_MARKET, - perpsMarket: ARBITRUM_SEPOLIA_PERPS_MARKET, - referrer: ARBITRUM_SEPOLIA_REFERRER, - susdcSpotId: ARBITRUM_SEPOLIA_SUSDC_SPOT_MARKET_ID, + // to base + spotMarket: BASE_SEPOLIA_SPOT_MARKET, + perpsMarket: BASE_SEPOLIA_PERPS_MARKET, + referrer: BASE_SEPOLIA_REFERRER, + susdcSpotId: BASE_SEPOLIA_SUSDC_SPOT_MARKET_ID, sstataSpotId: 0, //todo we are not deploying this stata release to - // arbitrum - aave: ARBITRUM_SEPOLIA_AAVE_POOL, + // base + aave: BASE_SEPOLIA_AAVE_POOL, stata: address(0), //todo we are not deploying this stata release to - // arbitrum - router: ARBITRUM_SEPOLIA_ROUTER + // base + router: BASE_SEPOLIA_ROUTER }); /// @custom:auxiliary - spotMarket = ISpotMarket(ARBITRUM_SEPOLIA_SPOT_MARKET); - perpsMarket = IPerpsMarket(ARBITRUM_SEPOLIA_PERPS_MARKET); - usdc = IERC20(ARBITRUM_SEPOLIA_USDC); + spotMarket = ISpotMarket(BASE_SEPOLIA_SPOT_MARKET); + perpsMarket = IPerpsMarket(BASE_SEPOLIA_PERPS_MARKET); + usdc = IERC20(BASE_SEPOLIA_USDC); susdc = IERC20(spotMarket.getSynth(zap.SSTATA_SPOT_ID())); - usdx = IERC20(ARBITRUM_SEPOLIA_USDX); - weth = IERC20(ARBITRUM_SEPOLIA_WETH); + usdx = IERC20(BASE_SEPOLIA_USDX); + weth = IERC20(BASE_SEPOLIA_WETH); _; } diff --git a/test/utils/BootstrapWithCurrentBlock.sol b/test/utils/BootstrapWithCurrentBlock.sol index 918e1cb..262757d 100644 --- a/test/utils/BootstrapWithCurrentBlock.sol +++ b/test/utils/BootstrapWithCurrentBlock.sol @@ -8,13 +8,13 @@ contract BootstrapWithCurrentBlock is Bootstrap { function setUp() public override { string memory BASE_RPC = vm.envString(BASE_RPC_REF); - string memory ARBITRUM_RPC = vm.envString(ARBITRUM_RPC_REF); - string memory ARBITRUM_SEPOLIA_RPC = - vm.envString(ARBITRUM_SEPOLIA_RPC_REF); + string memory BASE_RPC = vm.envString(BASE_RPC_REF); + string memory BASE_SEPOLIA_RPC = + vm.envString(BASE_SEPOLIA_RPC_REF); BASE = vm.createFork(BASE_RPC); - ARBITRUM = vm.createFork(ARBITRUM_RPC); - ARBITRUM_SEPOLIA = vm.createFork(ARBITRUM_SEPOLIA_RPC); + BASE = vm.createFork(BASE_RPC); + BASE_SEPOLIA = vm.createFork(BASE_SEPOLIA_RPC); headers.push("Content-Type: application/json"); } diff --git a/test/utils/Constants.sol b/test/utils/Constants.sol index 5e6a9cf..21f0e65 100644 --- a/test/utils/Constants.sol +++ b/test/utils/Constants.sol @@ -16,24 +16,24 @@ contract Constants { /// @custom:forks string constant BASE_RPC_REF = "BASE_RPC"; - string constant ARBITRUM_RPC_REF = "ARBITRUM_RPC"; - string constant ARBITRUM_SEPOLIA_RPC_REF = "ARBITRUM_SEPOLIA_RPC"; + string constant BASE_RPC_REF = "BASE_RPC"; + string constant BASE_SEPOLIA_RPC_REF = "BASE_SEPOLIA_RPC"; uint256 constant BASE_FORK_BLOCK = 26_606_911; - uint256 constant ARBITRUM_FORK_BLOCK = 256_615_000; - uint256 constant ARBITRUM_SEPOLIA_FORK_BLOCK = 85_443_000; + uint256 constant BASE_FORK_BLOCK = 256_615_000; + uint256 constant BASE_SEPOLIA_FORK_BLOCK = 85_443_000; uint256 constant BASE_CHAIN_ID = 8453; - uint256 constant ARBITRUM_CHAIN_ID = 42_161; + uint256 constant BASE_CHAIN_ID = 42_161; /// @custom:values address constant ACTOR = 0x7777777777777777777777777777777777777777; uint256 constant DEFAULT_MIN_AMOUNT_OUT = 0; /// @custom:tokens - address constant ARBITRUM_WETH = 0x82aF49447D8a07e3bd95BD0d56f35241523fBab1; - address constant ARBITRUM_TBTC = 0x6c84a8f1c29108F47a79964b5Fe888D4f4D0dE40; - address constant ARBITRUM_SEPOLIA_WETH = address(0); + address constant BASE_WETH = 0x82aF49447D8a07e3bd95BD0d56f35241523fBab1; + address constant BASE_TBTC = 0x6c84a8f1c29108F47a79964b5Fe888D4f4D0dE40; + address constant BASE_SEPOLIA_WETH = address(0); address constant BASE_WETH = 0x4200000000000000000000000000000000000006; address constant BASE_TBTC = 0x236aa50979D5f3De3Bd1Eeb40E81137F22ab794b; From 9d746b2521a999d45f899475e624ebdc0779d133 Mon Sep 17 00:00:00 2001 From: Moss Date: Thu, 6 Mar 2025 14:15:53 +0100 Subject: [PATCH 14/24] fmt --- script/Deploy.s.sol | 11 +++++++---- test/Aave.t.sol | 3 ++- test/Burn.t.sol | 8 +++----- test/Buy.t.sol | 2 +- test/utils/Bootstrap.sol | 19 ++++--------------- test/utils/BootstrapWithCurrentBlock.sol | 3 +-- 6 files changed, 18 insertions(+), 28 deletions(-) diff --git a/script/Deploy.s.sol b/script/Deploy.s.sol index 125fa8c..0ee4630 100644 --- a/script/Deploy.s.sol +++ b/script/Deploy.s.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.27; import {Script} from "../lib/forge-std/src/Script.sol"; import {Flush, Zap} from "../src/Zap.sol"; -import {BaseSepolia, Base} from "./utils/Parameters.sol"; +import {Base, BaseSepolia} from "./utils/Parameters.sol"; /// @title zap deployment script /// @author @jaredborders @@ -80,14 +80,17 @@ contract DeployBaseSepolia is Deploy, BaseSepolia { Zap zap = deploySystem({ usdc: base_SEPOLIA_USDC, usdx: base_SEPOLIA_USDX, - sstata: address(0), //todo we are not deploying this stata release to base + sstata: address(0), //todo we are not deploying this stata release + // to base spotMarket: base_SEPOLIA_SPOT_MARKET, perpsMarket: base_SEPOLIA_PERPS_MARKET, referrer: base_SEPOLIA_REFERRER, susdcSpotId: base_SEPOLIA_SUSDC_SPOT_MARKET_ID, - sstataSpotId: 0, //todo we are not deploying this stata release to base + sstataSpotId: 0, //todo we are not deploying this stata release to + // base aave: base_SEPOLIA_AAVE_POOL, - stata: address(0), //todo we are not deploying this stata release to base + stata: address(0), //todo we are not deploying this stata release to + // base router: base_SEPOLIA_ROUTER }); Flush(address(zap)).nominatePlumber(base_SEPOLIA_PDAO); diff --git a/test/Aave.t.sol b/test/Aave.t.sol index d1f2a61..af8b2b1 100644 --- a/test/Aave.t.sol +++ b/test/Aave.t.sol @@ -14,7 +14,8 @@ import { } from "./utils/Bootstrap.sol"; contract AaveTest is Bootstrap, Errors { -/// @custom:disabled no stata on base? TODO: check if there is stata on base and add this test back if there is +/// @custom:disabled no stata on base? TODO: check if there is stata on base and +/// add this test back if there is // function test_executeOperation_only_aave( // address caller, // address a, diff --git a/test/Burn.t.sol b/test/Burn.t.sol index 4e8dabf..2292881 100644 --- a/test/Burn.t.sol +++ b/test/Burn.t.sol @@ -16,7 +16,8 @@ import "forge-std/console2.sol"; contract BurnTest is Bootstrap { - /// @custom:disabled no stata on base? TODO: add back if there is stata on base + /// @custom:disabled no stata on base? TODO: add back if there is stata on + /// base // /// @custom:todo // ///@notice passes at block 269_610_923 // function test_burn_base(uint32 amount) public base { @@ -48,9 +49,6 @@ contract BurnTest is Bootstrap { function test_burn_base(uint32 amount) public base {} /// @custom:todo - function test_burn_base_sepolia(uint32 amount) - public - base_sepolia - {} + function test_burn_base_sepolia(uint32 amount) public base_sepolia {} } diff --git a/test/Buy.t.sol b/test/Buy.t.sol index 0fcec6d..cc1b5a4 100644 --- a/test/Buy.t.sol +++ b/test/Buy.t.sol @@ -33,7 +33,7 @@ contract BuyTest is Bootstrap { } /// TODO: add back test for base - /// @custom:disabled no stata on base? + /// @custom:disabled no stata on base? // function test_buy_base(uint32 amount) public base { // _spin(ACTOR, usdx, amount, address(zap)); // assertEq(usdx.balanceOf(ACTOR), amount); diff --git a/test/utils/Bootstrap.sol b/test/utils/Bootstrap.sol index 64c2a28..0dbaa6b 100644 --- a/test/utils/Bootstrap.sol +++ b/test/utils/Bootstrap.sol @@ -2,9 +2,7 @@ pragma solidity 0.8.27; import {Deploy} from "../../script/Deploy.s.sol"; -import { - Base, BaseSepolia, Base -} from "../../script/utils/Parameters.sol"; +import {Base, Base, BaseSepolia} from "../../script/utils/Parameters.sol"; import {Errors, IERC20, IPool, Reentrancy, Zap} from "../../src/Zap.sol"; import {IPerpsMarket, ISpotMarket} from "../interfaces/ISynthetix.sol"; @@ -14,14 +12,7 @@ import {stdJson} from "forge-std/StdJson.sol"; import {Test} from "forge-std/Test.sol"; import {Surl} from "surl/src/Surl.sol"; -contract Bootstrap is - Test, - Deploy, - Base, - Base, - BaseSepolia, - Constants -{ +contract Bootstrap is Test, Deploy, Base, Base, BaseSepolia, Constants { using Surl for *; using stdJson for string; @@ -49,13 +40,11 @@ contract Bootstrap is function setUp() public virtual { string memory BASE_RPC = vm.envString(BASE_RPC_REF); string memory BASE_RPC = vm.envString(BASE_RPC_REF); - string memory BASE_SEPOLIA_RPC = - vm.envString(BASE_SEPOLIA_RPC_REF); + string memory BASE_SEPOLIA_RPC = vm.envString(BASE_SEPOLIA_RPC_REF); BASE = vm.createFork(BASE_RPC, BASE_FORK_BLOCK); BASE = vm.createFork(BASE_RPC, BASE_FORK_BLOCK); - BASE_SEPOLIA = - vm.createFork(BASE_SEPOLIA_RPC, BASE_SEPOLIA_FORK_BLOCK); + BASE_SEPOLIA = vm.createFork(BASE_SEPOLIA_RPC, BASE_SEPOLIA_FORK_BLOCK); headers.push("Content-Type: application/json"); } diff --git a/test/utils/BootstrapWithCurrentBlock.sol b/test/utils/BootstrapWithCurrentBlock.sol index 262757d..147ae3b 100644 --- a/test/utils/BootstrapWithCurrentBlock.sol +++ b/test/utils/BootstrapWithCurrentBlock.sol @@ -9,8 +9,7 @@ contract BootstrapWithCurrentBlock is Bootstrap { function setUp() public override { string memory BASE_RPC = vm.envString(BASE_RPC_REF); string memory BASE_RPC = vm.envString(BASE_RPC_REF); - string memory BASE_SEPOLIA_RPC = - vm.envString(BASE_SEPOLIA_RPC_REF); + string memory BASE_SEPOLIA_RPC = vm.envString(BASE_SEPOLIA_RPC_REF); BASE = vm.createFork(BASE_RPC); BASE = vm.createFork(BASE_RPC); From 92a76f779116626c54374dbab52934a6967d23f2 Mon Sep 17 00:00:00 2001 From: Moss Date: Thu, 6 Mar 2025 20:25:41 +0100 Subject: [PATCH 15/24] fixed base sepolia errors --- script/Deploy.s.sol | 18 +++++----- script/utils/Parameters.sol | 10 +++--- test/Aave.t.sol | 36 ++++++++++---------- test/Burn.t.sol | 4 --- test/Flush.t.sol | 2 +- test/utils/Bootstrap.sol | 42 ++---------------------- test/utils/BootstrapWithCurrentBlock.sol | 2 -- test/utils/Constants.sol | 7 +--- 8 files changed, 37 insertions(+), 84 deletions(-) diff --git a/script/Deploy.s.sol b/script/Deploy.s.sol index 0ee4630..2ecd67c 100644 --- a/script/Deploy.s.sol +++ b/script/Deploy.s.sol @@ -78,22 +78,22 @@ contract DeployBaseSepolia is Deploy, BaseSepolia { function run() public broadcast { Zap zap = deploySystem({ - usdc: base_SEPOLIA_USDC, - usdx: base_SEPOLIA_USDX, + usdc: BASE_SEPOLIA_USDC, + usdx: BASE_SEPOLIA_USDX, sstata: address(0), //todo we are not deploying this stata release // to base - spotMarket: base_SEPOLIA_SPOT_MARKET, - perpsMarket: base_SEPOLIA_PERPS_MARKET, - referrer: base_SEPOLIA_REFERRER, - susdcSpotId: base_SEPOLIA_SUSDC_SPOT_MARKET_ID, + spotMarket: BASE_SEPOLIA_SPOT_MARKET, + perpsMarket: BASE_SEPOLIA_PERPS_MARKET, + referrer: BASE_SEPOLIA_REFERRER, + susdcSpotId: BASE_SEPOLIA_SUSDC_SPOT_MARKET_ID, sstataSpotId: 0, //todo we are not deploying this stata release to // base - aave: base_SEPOLIA_AAVE_POOL, + aave: BASE_SEPOLIA_AAVE_POOL, stata: address(0), //todo we are not deploying this stata release to // base - router: base_SEPOLIA_ROUTER + router: BASE_SEPOLIA_ROUTER }); - Flush(address(zap)).nominatePlumber(base_SEPOLIA_PDAO); + Flush(address(zap)).nominatePlumber(BASE_SEPOLIA_PDAO); } } diff --git a/script/utils/Parameters.sol b/script/utils/Parameters.sol index 8d956ca..295deca 100644 --- a/script/utils/Parameters.sol +++ b/script/utils/Parameters.sol @@ -32,15 +32,15 @@ contract BaseSepolia { address BASE_SEPOLIA_PDAO = address(0); /// @custom:synthetix - address BASE_SEPOLIA_USDC = 0x0; - address BASE_SEPOLIA_USDX = 0x0; - address BASE_SEPOLIA_SPOT_MARKET = 0x0; - address BASE_SEPOLIA_PERPS_MARKET = 0x0; + address BASE_SEPOLIA_USDC = 0x5dEaC602762362FE5f135FA5904351916053cF70; + address BASE_SEPOLIA_USDX = address(0); + address BASE_SEPOLIA_SPOT_MARKET = address(0); + address BASE_SEPOLIA_PERPS_MARKET = address(0); address BASE_SEPOLIA_REFERRER = address(0); uint128 BASE_SEPOLIA_SUSDC_SPOT_MARKET_ID = 0; /// @custom:aave - address BASE_SEPOLIA_AAVE_POOL = 0x0; + address BASE_SEPOLIA_AAVE_POOL = address(0); /// @custom:odos address BASE_SEPOLIA_ROUTER = address(0); diff --git a/test/Aave.t.sol b/test/Aave.t.sol index af8b2b1..74048c7 100644 --- a/test/Aave.t.sol +++ b/test/Aave.t.sol @@ -14,22 +14,22 @@ import { } from "./utils/Bootstrap.sol"; contract AaveTest is Bootstrap, Errors { -/// @custom:disabled no stata on base? TODO: check if there is stata on base and -/// add this test back if there is -// function test_executeOperation_only_aave( -// address caller, -// address a, -// uint256 b, -// uint256 c, -// bytes calldata d -// ) -// public -// base -// { -// if (caller != zap.AAVE()) { -// vm.prank(caller); -// vm.expectRevert(abi.encodeWithSelector(OnlyAave.selector, caller)); -// zap.executeOperation(a, b, c, a, d); -// } -// } + + function test_executeOperation_only_aave( + address caller, + address a, + uint256 b, + uint256 c, + bytes calldata d + ) + public + base + { + if (caller != zap.AAVE()) { + vm.prank(caller); + vm.expectRevert(abi.encodeWithSelector(OnlyAave.selector, caller)); + zap.executeOperation(a, b, c, a, d); + } + } + } diff --git a/test/Burn.t.sol b/test/Burn.t.sol index 2292881..2349f4c 100644 --- a/test/Burn.t.sol +++ b/test/Burn.t.sol @@ -47,8 +47,4 @@ contract BurnTest is Bootstrap { /// @custom:todo function test_burn_base(uint32 amount) public base {} - - /// @custom:todo - function test_burn_base_sepolia(uint32 amount) public base_sepolia {} - } diff --git a/test/Flush.t.sol b/test/Flush.t.sol index 215460f..62f50a7 100644 --- a/test/Flush.t.sol +++ b/test/Flush.t.sol @@ -15,6 +15,6 @@ import { contract FlushTest is Bootstrap { /// @custom:todo - function test_flush(uint32 amount) public base_sepolia {} + function test_flush(uint32 amount) public base {} } diff --git a/test/utils/Bootstrap.sol b/test/utils/Bootstrap.sol index 0dbaa6b..70632f1 100644 --- a/test/utils/Bootstrap.sol +++ b/test/utils/Bootstrap.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.27; import {Deploy} from "../../script/Deploy.s.sol"; -import {Base, Base, BaseSepolia} from "../../script/utils/Parameters.sol"; +import {Base, BaseSepolia} from "../../script/utils/Parameters.sol"; import {Errors, IERC20, IPool, Reentrancy, Zap} from "../../src/Zap.sol"; import {IPerpsMarket, ISpotMarket} from "../interfaces/ISynthetix.sol"; @@ -12,14 +12,13 @@ import {stdJson} from "forge-std/StdJson.sol"; import {Test} from "forge-std/Test.sol"; import {Surl} from "surl/src/Surl.sol"; -contract Bootstrap is Test, Deploy, Base, Base, BaseSepolia, Constants { +contract Bootstrap is Test, Deploy, Base, BaseSepolia, Constants { using Surl for *; using stdJson for string; /// @custom:forks uint256 BASE; - uint256 BASE; uint256 BASE_SEPOLIA; /// @custom:target @@ -38,13 +37,11 @@ contract Bootstrap is Test, Deploy, Base, Base, BaseSepolia, Constants { string[] headers; function setUp() public virtual { - string memory BASE_RPC = vm.envString(BASE_RPC_REF); string memory BASE_RPC = vm.envString(BASE_RPC_REF); string memory BASE_SEPOLIA_RPC = vm.envString(BASE_SEPOLIA_RPC_REF); BASE = vm.createFork(BASE_RPC, BASE_FORK_BLOCK); - BASE = vm.createFork(BASE_RPC, BASE_FORK_BLOCK); - BASE_SEPOLIA = vm.createFork(BASE_SEPOLIA_RPC, BASE_SEPOLIA_FORK_BLOCK); + BASE_SEPOLIA = vm.createFork(BASE_SEPOLIA_RPC /* , BASE_SEPOLIA_FORK_BLOCK */); headers.push("Content-Type: application/json"); } @@ -81,39 +78,6 @@ contract Bootstrap is Test, Deploy, Base, Base, BaseSepolia, Constants { _; } - modifier base() { - /// @custom:fork - vm.selectFork(BASE); - - /// @custom:target - zap = deploySystem({ - usdc: BASE_USDC, - usdx: BASE_USDX, - sstata: address(0), //todo we are not deploying this stata release - // to base - spotMarket: BASE_SPOT_MARKET, - perpsMarket: BASE_PERPS_MARKET, - referrer: BASE_REFERRER, - susdcSpotId: BASE_SUSDC_SPOT_MARKET_ID, - sstataSpotId: 0, //todo we are not deploying this stata release to - // base - aave: BASE_AAVE_POOL, - stata: address(0), //todo we are not deploying this stata release to - // base - router: BASE_ROUTER - }); - - /// @custom:auxiliary - spotMarket = ISpotMarket(BASE_SPOT_MARKET); - perpsMarket = IPerpsMarket(BASE_PERPS_MARKET); - usdc = IERC20(BASE_USDC); - susdc = IERC20(spotMarket.getSynth(zap.SSTATA_SPOT_ID())); - usdx = IERC20(BASE_USDX); - weth = IERC20(BASE_WETH); - tbtc = IERC20(BASE_TBTC); - _; - } - modifier base_sepolia() { /// @custom:fork vm.selectFork(BASE_SEPOLIA); diff --git a/test/utils/BootstrapWithCurrentBlock.sol b/test/utils/BootstrapWithCurrentBlock.sol index 147ae3b..5098880 100644 --- a/test/utils/BootstrapWithCurrentBlock.sol +++ b/test/utils/BootstrapWithCurrentBlock.sol @@ -7,11 +7,9 @@ import "forge-std/console2.sol"; contract BootstrapWithCurrentBlock is Bootstrap { function setUp() public override { - string memory BASE_RPC = vm.envString(BASE_RPC_REF); string memory BASE_RPC = vm.envString(BASE_RPC_REF); string memory BASE_SEPOLIA_RPC = vm.envString(BASE_SEPOLIA_RPC_REF); - BASE = vm.createFork(BASE_RPC); BASE = vm.createFork(BASE_RPC); BASE_SEPOLIA = vm.createFork(BASE_SEPOLIA_RPC); diff --git a/test/utils/Constants.sol b/test/utils/Constants.sol index 21f0e65..862db39 100644 --- a/test/utils/Constants.sol +++ b/test/utils/Constants.sol @@ -16,23 +16,18 @@ contract Constants { /// @custom:forks string constant BASE_RPC_REF = "BASE_RPC"; - string constant BASE_RPC_REF = "BASE_RPC"; string constant BASE_SEPOLIA_RPC_REF = "BASE_SEPOLIA_RPC"; uint256 constant BASE_FORK_BLOCK = 26_606_911; - uint256 constant BASE_FORK_BLOCK = 256_615_000; - uint256 constant BASE_SEPOLIA_FORK_BLOCK = 85_443_000; + // uint256 constant BASE_SEPOLIA_FORK_BLOCK = 0; uint256 constant BASE_CHAIN_ID = 8453; - uint256 constant BASE_CHAIN_ID = 42_161; /// @custom:values address constant ACTOR = 0x7777777777777777777777777777777777777777; uint256 constant DEFAULT_MIN_AMOUNT_OUT = 0; /// @custom:tokens - address constant BASE_WETH = 0x82aF49447D8a07e3bd95BD0d56f35241523fBab1; - address constant BASE_TBTC = 0x6c84a8f1c29108F47a79964b5Fe888D4f4D0dE40; address constant BASE_SEPOLIA_WETH = address(0); address constant BASE_WETH = 0x4200000000000000000000000000000000000006; address constant BASE_TBTC = 0x236aa50979D5f3De3Bd1Eeb40E81137F22ab794b; From cec01ef44c116228b487a0763e4f7417624de64a Mon Sep 17 00:00:00 2001 From: Moss Date: Thu, 6 Mar 2025 20:27:54 +0100 Subject: [PATCH 16/24] fmt --- test/Burn.t.sol | 42 +++++++++++++++++----------------------- test/utils/Bootstrap.sol | 3 ++- 2 files changed, 20 insertions(+), 25 deletions(-) diff --git a/test/Burn.t.sol b/test/Burn.t.sol index 2349f4c..51589d8 100644 --- a/test/Burn.t.sol +++ b/test/Burn.t.sol @@ -15,36 +15,30 @@ import { import "forge-std/console2.sol"; contract BurnTest is Bootstrap { +/// @custom:TODO +// ///@notice passes at block 269_610_923 +// function test_burn_base(uint32 amount) public base { +// IERC20 A_USDX = IERC20(BASE_USDX); +// uint128 accountID = +// 170_141_183_460_469_231_731_687_303_715_884_105_766; - /// @custom:disabled no stata on base? TODO: add back if there is stata on - /// base - // /// @custom:todo - // ///@notice passes at block 269_610_923 - // function test_burn_base(uint32 amount) public base { - // IERC20 A_USDX = IERC20(Base_USDX); - // uint128 accountID = - // 170_141_183_460_469_231_731_687_303_715_884_105_766; +// address accountOwner = 0x12a41a75793b6ac2cdDAF680798BB461a1024a46; - // address accountOwner = 0x12a41a75793b6ac2cdDAF680798BB461a1024a46; +// uint256 debt = IPerpsMarket(zap.PERPS_MARKET()).debt(accountID); - // uint256 debt = IPerpsMarket(zap.PERPS_MARKET()).debt(accountID); +// vm.assume(amount > 1e6 && amount <= debt); - // vm.assume(amount > 1e6 && amount <= debt); +// uint256 balBefore = A_USDX.balanceOf(accountOwner); - // uint256 balBefore = A_USDX.balanceOf(accountOwner); +// vm.startPrank(accountOwner); +// A_USDX.approve(address(zap), type(uint256).max); - // vm.startPrank(accountOwner); - // A_USDX.approve(address(zap), type(uint256).max); +// zap.burn(amount, accountID); - // zap.burn(amount, accountID); +// uint256 balAfter = A_USDX.balanceOf(accountOwner); +// uint256 debtAfter = IPerpsMarket(zap.PERPS_MARKET()).debt(accountID); - // uint256 balAfter = A_USDX.balanceOf(accountOwner); - // uint256 debtAfter = IPerpsMarket(zap.PERPS_MARKET()).debt(accountID); - - // assertEq(balAfter, balBefore - amount); - // assertEq(debt - amount, debtAfter); - // } - - /// @custom:todo - function test_burn_base(uint32 amount) public base {} +// assertEq(balAfter, balBefore - amount); +// assertEq(debt - amount, debtAfter); +// } } diff --git a/test/utils/Bootstrap.sol b/test/utils/Bootstrap.sol index 70632f1..84cecf4 100644 --- a/test/utils/Bootstrap.sol +++ b/test/utils/Bootstrap.sol @@ -41,7 +41,8 @@ contract Bootstrap is Test, Deploy, Base, BaseSepolia, Constants { string memory BASE_SEPOLIA_RPC = vm.envString(BASE_SEPOLIA_RPC_REF); BASE = vm.createFork(BASE_RPC, BASE_FORK_BLOCK); - BASE_SEPOLIA = vm.createFork(BASE_SEPOLIA_RPC /* , BASE_SEPOLIA_FORK_BLOCK */); + BASE_SEPOLIA = + vm.createFork(BASE_SEPOLIA_RPC /* , BASE_SEPOLIA_FORK_BLOCK */ ); headers.push("Content-Type: application/json"); } From a19a6f31c96c3d02c8521cff01195256e40d4caa Mon Sep 17 00:00:00 2001 From: Moss Date: Thu, 6 Mar 2025 20:33:35 +0100 Subject: [PATCH 17/24] removed extra arbitrum tests that were the same as base --- test/Buy.t.sol | 20 -------------- test/OdosAPITest.t.sol | 22 --------------- test/Sell.t.sol | 26 ------------------ test/Swap.from.t.sol | 61 ------------------------------------------ test/Unwind.t.sol | 1 - test/Unwrap.t.sol | 27 ------------------- test/Withdraw.t.sol | 30 --------------------- test/Wrap.t.sol | 19 ------------- test/Zap.in.t.sol | 17 ------------ test/Zap.out.t.sol | 18 ------------- 10 files changed, 241 deletions(-) diff --git a/test/Buy.t.sol b/test/Buy.t.sol index cc1b5a4..3bc38a6 100644 --- a/test/Buy.t.sol +++ b/test/Buy.t.sol @@ -32,24 +32,4 @@ contract BuyTest is Bootstrap { assertGe(susdc.balanceOf(ACTOR), DEFAULT_MIN_AMOUNT_OUT); } - /// TODO: add back test for base - /// @custom:disabled no stata on base? - // function test_buy_base(uint32 amount) public base { - // _spin(ACTOR, usdx, amount, address(zap)); - // assertEq(usdx.balanceOf(ACTOR), amount); - // assertEq(susdc.balanceOf(ACTOR), 0); - // vm.startPrank(ACTOR); - // (uint256 received, address synth) = zap.buy({ - // _synthId: zap.SUSDC_SPOT_ID(), - // _amount: amount, - // _minAmountOut: DEFAULT_MIN_AMOUNT_OUT, - // _receiver: ACTOR - // }); - // vm.stopPrank(); - // assertEq(synth, address(susdc)); - // assertGe(received, DEFAULT_MIN_AMOUNT_OUT); - // assertEq(usdx.balanceOf(ACTOR), 0); - // assertGe(susdc.balanceOf(ACTOR), DEFAULT_MIN_AMOUNT_OUT); - // } - } diff --git a/test/OdosAPITest.t.sol b/test/OdosAPITest.t.sol index c111777..f73fa50 100644 --- a/test/OdosAPITest.t.sol +++ b/test/OdosAPITest.t.sol @@ -35,26 +35,4 @@ contract OdosAPITest is Bootstrap { assertEq(assembleStatus, 200); } - /// @custom:disabled no stata on base - // function test_odos_api_base() public base { - // (uint256 quoteStatus, bytes memory quoteData) = getOdosQuote( - // BASE_CHAIN_ID, - // BASE_WETH, - // 1 ether, - // BASE_USDC, - // DEFAULT_PROPORTION, - // DEFAULT_SLIPPAGE, - // address(zap) - // ); - - // assertEq(quoteStatus, 200); - - // string memory pathId = - // abi.decode(vm.parseJson(string(quoteData), ".pathId"), (string)); - - // (uint256 assembleStatus,) = odosAssemble(pathId); - - // assertEq(assembleStatus, 200); - // } - } diff --git a/test/Sell.t.sol b/test/Sell.t.sol index a4e7710..ca86a70 100644 --- a/test/Sell.t.sol +++ b/test/Sell.t.sol @@ -38,30 +38,4 @@ contract SellTest is Bootstrap { assertEq(susdc.balanceOf(ACTOR), 0); } - ///TODO: add this test back - /// @custom:disabled no stata on base - // function test_sell_base(uint32 amount) public base { - // _spin(ACTOR, usdx, amount, address(zap)); - // vm.startPrank(ACTOR); - // (uint256 received,) = zap.buy({ - // _synthId: zap.SUSDC_SPOT_ID(), - // _amount: amount, - // _minAmountOut: DEFAULT_MIN_AMOUNT_OUT, - // _receiver: ACTOR - // }); - // assertEq(usdx.balanceOf(ACTOR), 0); - // assertGe(susdc.balanceOf(ACTOR), DEFAULT_MIN_AMOUNT_OUT); - // susdc.approve(address(zap), type(uint256).max); - // received = zap.sell({ - // _synthId: zap.SUSDC_SPOT_ID(), - // _amount: received, - // _minAmountOut: DEFAULT_MIN_AMOUNT_OUT, - // _receiver: ACTOR - // }); - // vm.stopPrank(); - // assertGe(received, DEFAULT_MIN_AMOUNT_OUT); - // assertGe(usdx.balanceOf(ACTOR), DEFAULT_MIN_AMOUNT_OUT); - // assertEq(susdc.balanceOf(ACTOR), 0); - // } - } diff --git a/test/Swap.from.t.sol b/test/Swap.from.t.sol index 10a532f..ca79ff5 100644 --- a/test/Swap.from.t.sol +++ b/test/Swap.from.t.sol @@ -46,67 +46,6 @@ contract SwapFromTest is BootstrapWithCurrentBlock { assertEq(weth.balanceOf(address(zap)), 0); } - /// @custom:disabled no stata on base - // function test_swap_from_weth_base() public base { - // { - // _spin(ACTOR, weth, DEFAULT_AMOUNT, address(zap)); - // assertEq(usdc.balanceOf(ACTOR), 0); - // assertEq(weth.balanceOf(ACTOR), DEFAULT_AMOUNT); - // assertEq(usdc.balanceOf(address(zap)), 0); - // assertEq(weth.balanceOf(address(zap)), 0); - - // pathId = getOdosQuotePathId( - // BASE_CHAIN_ID, BASE_WETH, DEFAULT_AMOUNT, - // BASE_USDC - // ); - - // swapPath = getAssemblePath(pathId); - // } - - // vm.startPrank(ACTOR); - // uint256 amountOut = zap.swapFrom({ - // _from: BASE_WETH, - // _path: swapPath, - // _amountIn: DEFAULT_AMOUNT, - // _receiver: ACTOR - // }); - - // assertEq(usdc.balanceOf(ACTOR), amountOut); - // assertEq(weth.balanceOf(ACTOR), 0); - // assertEq(usdc.balanceOf(address(zap)), 0); - // assertEq(weth.balanceOf(address(zap)), 0); - // } - - // function test_swap_from_tbtc_base() public base { - // { - // _spin(ACTOR, tbtc, DEFAULT_AMOUNT, address(zap)); - // assertEq(usdc.balanceOf(ACTOR), 0); - // assertEq(tbtc.balanceOf(ACTOR), DEFAULT_AMOUNT); - // assertEq(usdc.balanceOf(address(zap)), 0); - // assertEq(tbtc.balanceOf(address(zap)), 0); - - // pathId = getOdosQuotePathId( - // BASE_CHAIN_ID, BASE_TBTC, DEFAULT_AMOUNT, - // BASE_USDC - // ); - - // swapPath = getAssemblePath(pathId); - // } - - // vm.startPrank(ACTOR); - // uint256 amountOut = zap.swapFrom({ - // _from: BASE_TBTC, - // _path: swapPath, - // _amountIn: DEFAULT_AMOUNT, - // _receiver: ACTOR - // }); - - // assertEq(usdc.balanceOf(ACTOR), amountOut); - // assertEq(tbtc.balanceOf(ACTOR), 0); - // assertEq(usdc.balanceOf(address(zap)), 0); - // assertEq(tbtc.balanceOf(address(zap)), 0); - // } - function test_swap_from_tbtc_base() public base { { _spin(ACTOR, tbtc, DEFAULT_AMOUNT, address(zap)); diff --git a/test/Unwind.t.sol b/test/Unwind.t.sol index 7b8234e..ed0d432 100644 --- a/test/Unwind.t.sol +++ b/test/Unwind.t.sol @@ -35,7 +35,6 @@ contract UnwindTest is Bootstrap, Errors { bytes swapPath; string pathId; - /// @custom:disabled no stata on base // function test_unwind_is_authorized() public base { // vm.prank(ACTOR); // vm.expectRevert(NotPermitted.selector); diff --git a/test/Unwrap.t.sol b/test/Unwrap.t.sol index e20b0e7..2678822 100644 --- a/test/Unwrap.t.sol +++ b/test/Unwrap.t.sol @@ -40,31 +40,4 @@ contract UnwrapTest is Bootstrap { assertEq(susdc.balanceOf(ACTOR), 0); } - /// @custom:disabled no stata on base - // function test_unwrap_base(uint32 amount) public base { - // _spin(ACTOR, usdc, amount, address(zap)); - // vm.startPrank(ACTOR); - // uint256 wrapped = zap.wrap({ - // _token: address(usdc), - // _synthId: zap.SUSDC_SPOT_ID(), - // _amount: amount, - // _minAmountOut: DEFAULT_MIN_AMOUNT_OUT, - // _receiver: ACTOR - // }); - // assertEq(usdc.balanceOf(ACTOR), 0); - // assertGe(susdc.balanceOf(ACTOR), DEFAULT_MIN_AMOUNT_OUT); - // susdc.approve(address(zap), type(uint256).max); - // uint256 unwrapped = zap.unwrap({ - // _token: address(usdc), - // _synthId: zap.SUSDC_SPOT_ID(), - // _amount: wrapped, - // _minAmountOut: DEFAULT_MIN_AMOUNT_OUT, - // _receiver: ACTOR - // }); - // vm.stopPrank(); - // assertGe(unwrapped, DEFAULT_MIN_AMOUNT_OUT); - // assertEq(usdc.balanceOf(ACTOR), amount); - // assertEq(susdc.balanceOf(ACTOR), 0); - // } - } diff --git a/test/Withdraw.t.sol b/test/Withdraw.t.sol index a99d6ff..7db8129 100644 --- a/test/Withdraw.t.sol +++ b/test/Withdraw.t.sol @@ -15,13 +15,6 @@ import { contract WithdrawTest is Bootstrap, Errors { - /// @custom:disabled no stata on base - // function test_withdraw_is_authorized_base() public base { - // vm.prank(ACTOR); - // vm.expectRevert(NotPermitted.selector); - // zap.withdraw(0, 0, 0, address(0)); - // } - function test_withdraw_is_authorized_base() public base { vm.prank(ACTOR); vm.expectRevert(NotPermitted.selector); @@ -50,27 +43,4 @@ contract WithdrawTest is Bootstrap, Errors { assertEq(usdx.balanceOf(ACTOR), amount); } - /// @custom:disabled no stata on base - // function test_withdraw_base() public base { - // uint32 amount = 1_000_000_000; - // _spin(ACTOR, usdx, amount, address(zap)); - // vm.startPrank(ACTOR); - // uint128 accountId = perpsMarket.createAccount(); - // int128 margin = int128(int32(amount)); - // usdx.approve(address(perpsMarket), type(uint256).max); - // perpsMarket.grantPermission( - // accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) - // ); - // perpsMarket.modifyCollateral(accountId, 0, margin); - // assertEq(usdx.balanceOf(ACTOR), 0); - // zap.withdraw({ - // _synthId: 0, - // _amount: amount, - // _accountId: accountId, - // _receiver: ACTOR - // }); - // vm.stopPrank(); - // assertEq(usdx.balanceOf(ACTOR), amount); - // } - } diff --git a/test/Wrap.t.sol b/test/Wrap.t.sol index cc332dd..b42f16b 100644 --- a/test/Wrap.t.sol +++ b/test/Wrap.t.sol @@ -32,23 +32,4 @@ contract WrapTest is Bootstrap { assertEq(susdc.balanceOf(ACTOR), wrapped); } - /// @custom:disabled no stata on base - // function test_wrap_base(uint32 amount) public base { - // _spin(ACTOR, usdc, amount, address(zap)); - // assertEq(usdc.balanceOf(ACTOR), amount); - // assertEq(susdc.balanceOf(ACTOR), 0); - // vm.startPrank(ACTOR); - // uint256 wrapped = zap.wrap({ - // _token: address(usdc), - // _synthId: zap.SUSDC_SPOT_ID(), - // _amount: amount, - // _minAmountOut: DEFAULT_MIN_AMOUNT_OUT, - // _receiver: ACTOR - // }); - // vm.stopPrank(); - // assertGe(wrapped, DEFAULT_MIN_AMOUNT_OUT); - // assertEq(usdc.balanceOf(ACTOR), 0); - // assertEq(susdc.balanceOf(ACTOR), wrapped); - // } - } diff --git a/test/Zap.in.t.sol b/test/Zap.in.t.sol index d598129..5d9368d 100644 --- a/test/Zap.in.t.sol +++ b/test/Zap.in.t.sol @@ -29,21 +29,4 @@ contract ZapInTest is Bootstrap { assertEq(sstata.balanceOf(ACTOR), zapped); } - /// @custom:disabled no stata on base - // function test_zap_in_base(uint32 amount) public base { - // _spin(ACTOR, usdc, amount, address(zap)); - // assertEq(usdc.balanceOf(ACTOR), amount); - // assertEq(usdx.balanceOf(ACTOR), 0); - // vm.startPrank(ACTOR); - // uint256 zapped = zap.zapIn({ - // _amount: amount, - // _minAmountOut: DEFAULT_MIN_AMOUNT_OUT, - // _receiver: ACTOR - // }); - // vm.stopPrank(); - // assertGe(zapped, DEFAULT_MIN_AMOUNT_OUT); - // assertEq(usdc.balanceOf(ACTOR), 0); - // assertEq(usdx.balanceOf(ACTOR), zapped); - // } - } diff --git a/test/Zap.out.t.sol b/test/Zap.out.t.sol index 378e257..a9068b8 100644 --- a/test/Zap.out.t.sol +++ b/test/Zap.out.t.sol @@ -41,22 +41,4 @@ contract ZapOutTest is Bootstrap { assertEq(sstata.balanceOf(ACTOR), 0); } - /// @custom:disabled no stata on base - // function test_zap_out_base(uint64 amount) public base { - // vm.assume(amount > 1e18); - // _spin(ACTOR, usdx, amount, address(zap)); - // assertEq(usdc.balanceOf(ACTOR), 0); - // assertEq(usdx.balanceOf(ACTOR), amount); - // vm.startPrank(ACTOR); - // uint256 zapped = zap.zapOut({ - // _amount: amount, - // _minAmountOut: DEFAULT_MIN_AMOUNT_OUT, - // _receiver: ACTOR - // }); - // vm.stopPrank(); - // assertGe(zapped, DEFAULT_MIN_AMOUNT_OUT); - // assertEq(usdc.balanceOf(ACTOR), zapped); - // assertEq(usdx.balanceOf(ACTOR), 0); - // } - } From 7ecc5cc79642d99fe6248a4895ed17a8ea025990 Mon Sep 17 00:00:00 2001 From: Moss Date: Thu, 6 Mar 2025 20:57:50 +0100 Subject: [PATCH 18/24] stopping point --- test/EndToEnd.t.sol | 3856 +++++++++++++++++++++---------------------- test/Unwind.t.sol | 10 +- 2 files changed, 1918 insertions(+), 1948 deletions(-) diff --git a/test/EndToEnd.t.sol b/test/EndToEnd.t.sol index 7a80459..a46f9eb 100644 --- a/test/EndToEnd.t.sol +++ b/test/EndToEnd.t.sol @@ -1,2042 +1,2012 @@ -/// TODO add back this test -/// @custom:disabled no stata on base? - -// // SPDX-License-Identifier: MIT -// pragma solidity 0.8.27; - -// import {Base} from "../script/utils/Parameters.sol"; -// import {IERC20, Zap} from "../src/Zap.sol"; -// import {Flush} from "../src/utils/Flush.sol"; -// import "./interfaces/ISynthetix.sol"; - -// import {Bootstrap} from "./utils/Bootstrap.sol"; -// import {Constants} from "./utils/Constants.sol"; -// import {OdosSwapData} from "./utils/OdosSwapData.sol"; -// import "forge-std/Test.sol"; - -// interface IPyth { - -// struct PythPrice { -// // Price -// int64 price; -// // Confidence interval around the price -// uint64 conf; -// // Price exponent -// int32 expo; -// // Unix timestamp describing when the price was published -// uint256 publishTime; -// } - -// function getPriceUnsafe(bytes32 id) -// external -// view -// returns (PythPrice memory price); - -// } - -// contract Attacker { - -// IERC20 usdc; -// address zap; - -// constructor(IERC20 _usdc, address _zap) { -// usdc = _usdc; -// zap = _zap; -// } - -// function sweep(IERC20 token) public { -// token.transfer(msg.sender, token.balanceOf(address(this))); -// } - -// receive() external payable { -// // could call back into zap to do another swap but that just pays -// more -// // fees, no real profit -// // could transfer usdc into zap for zap to be able to pay back the -// // original caller but that is also just shuffling your own assets -// // around -// // cant call reenter into executeOperation because of access controls -// } - -// } - -// contract EndToEndTest is Test, Base, Constants, OdosSwapData { - -// Zap zap; - -// ISpotMarket spotMarket; -// IPerpsMarket perpsMarket; - -// IERC20 usdc; -// IERC20 susdc; -// IERC20 usdx; -// IERC20 weth; - -// uint128 smallAccountIdNoOi = -// 170_141_183_460_469_231_731_687_303_715_884_106_052; -// address smallAccountNoOiOwner = -// 0xbd400F9a17DC18bc031DBF5ffCD2689F4BF650dD; - -// uint128 smallAccountIdWithOi = -// 170_141_183_460_469_231_731_687_303_715_884_106_146; -// address smallAccountWithOiOwner = -// 0x46232CbDB0512Ca7B00B8271e285BF8447F1330b; - -// uint128 largeAccountIdNoOi = -// 170_141_183_460_469_231_731_687_303_715_884_105_759; -// address largeAccountNoOiOwner = -// 0x626a7d9f7bBCaEB1Fa88E8128Bec8f2Dd48b2b4d; - -// uint128 largeAccountIdWithOi = -// 170_141_183_460_469_231_731_687_303_715_884_105_846; -// address largeAccountWithOiOwner = -// 0x1C1e747A6BE850549E9655addf59FD9e7cC2D4dC; - -// string RPC = vm.envString("BASE_RPC"); -// mapping(string => uint256) FORK; - -// modifier selectFork(uint256 fork) { -// initilizeFork(fork); -// _; -// } - -// function setUp() public { -// FORK["0p0001_wrong"] = vm.createFork(RPC, blockNumber_0p0001_wrong); -// FORK["0p001_wrong"] = vm.createFork(RPC, blockNumber_0p001_wrong); -// FORK["0p01_wrong"] = vm.createFork(RPC, blockNumber_0p01_wrong); -// FORK["0p1_wrong"] = vm.createFork(RPC, blockNumber_0p1_wrong); -// FORK["1_wrong"] = vm.createFork(RPC, blockNumber_1_wrong); -// FORK["10_wrong"] = vm.createFork(RPC, blockNumber_10_wrong); -// FORK["100_wrong"] = vm.createFork(RPC, blockNumber_100_wrong); - -// FORK["0p0001_zap"] = vm.createFork(RPC, blockNumber_0p0001_zap); -// FORK["0p001_zap"] = vm.createFork(RPC, blockNumber_0p001_zap); -// FORK["0p01_zap"] = vm.createFork(RPC, blockNumber_0p01_zap); -// FORK["0p1_zap"] = vm.createFork(RPC, blockNumber_0p1_zap); -// FORK["1_zap"] = vm.createFork(RPC, blockNumber_1_zap); -// FORK["10_zap"] = vm.createFork(RPC, blockNumber_10_zap); -// FORK["100_zap"] = vm.createFork(RPC, blockNumber_100_zap); - -// FORK["1000_attacker"] = vm.createFork(RPC, -// blockNumber_1000_attacker); -// } - -// function initilizeFork(uint256 fork) public { -// vm.selectFork(fork); - -// spotMarket = ISpotMarket(BASE_SPOT_MARKET); -// perpsMarket = IPerpsMarket(BASE_PERPS_MARKET); - -// usdc = IERC20(BASE_USDC); -// usdx = IERC20(BASE_USDX); -// weth = IERC20(BASE_WETH); - -// uint128 synthMarketId = BASE_SUSDC_SPOT_MARKET_ID; - -// susdc = IERC20(spotMarket.getSynth(synthMarketId)); - -// // create Zap contract to use actual sUSDC synth -// zap = new Zap({ -// _usdc: address(usdc), -// _usdx: address(usdx), -// _sstata: address(0), // no stata on base -// _spotMarket: address(spotMarket), -// _perpsMarket: address(perpsMarket), -// _referrer: BASE_REFERRER, -// _susdcSpotId: synthMarketId, -// _sstataSpotId: 0, // no stata on base -// _aave: BASE_AAVE_POOL, -// _stata: address(0), // no stata on base -// _router: BASE_ROUTER -// }); - -// IPyth pyth = IPyth(0xd74CdD8Eef0E97a5a7678F907991316f88E7965A); - -// vm.mockCall( -// address(pyth), -// abi.encodeWithSignature( -// "getPriceUnsafe(bytes32)", -// 0xeaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a -// ), -// abi.encode( -// 99_990_737, -// 105_741, -// 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_928, -// block.timestamp -// ) -// ); -// vm.mockCall( -// address(pyth), -// abi.encodeWithSignature( -// "getPriceUnsafe(bytes32)", -// 0x6ec879b1e9963de5ee97e9c8710b742d6228252a5e2ca12d4ae81d7fe5ee8c5d -// ), -// abi.encode(99_874_029, 139_807, int32(-8), block.timestamp) -// ); -// vm.mockCall( -// address(pyth), -// abi.encodeWithSignature( -// "getPriceUnsafe(bytes32)", -// 0xff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace -// ), -// abi.encode(314_393_291_700, 176_780_592, int32(-8), -// block.timestamp) -// ); -// vm.mockCall( -// address(pyth), -// abi.encodeWithSignature( -// "getPriceUnsafe(bytes32)", -// 0xd69731a2e74ac1ce884fc3890f7ee324b6deb66147055249568869ed700882e4 -// ), -// abi.encode(191_914, 287, int32(-10), block.timestamp) -// ); -// vm.mockCall( -// address(pyth), -// abi.encodeWithSignature( -// "getPriceUnsafe(bytes32)", -// 0xe62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43 -// ), -// abi.encode( -// 9_798_709_797_025, 5_649_852_176, int32(-8), block.timestamp -// ) -// ); -// } - -// function _spin(address eoa, IERC20 token, uint256 amount) internal { -// vm.assume(amount > 0); -// deal(address(token), eoa, amount); -// } - -// // this test fails because unspent input asses it not refunded -// function testOdosSwapSmall_Success() -// public -// selectFork(FORK["0p0001_zap"]) -// { -// address user = vm.addr(1); -// uint256 amount = 1e18; -// _spin(user, weth, amount); - -// uint256 wethBefore = weth.balanceOf(address(user)); -// uint256 usdcBefore = usdc.balanceOf(address(user)); - -// vm.startPrank(user); -// weth.approve(address(zap), amount); -// zap.swapFrom(address(weth), swapData_0p0001_zap, amount, user); -// vm.stopPrank(); - -// assertEq(weth.balanceOf(address(user)), wethBefore - 0.0001 ether); -// assertGt( -// usdc.balanceOf(address(user)), -// usdcBefore + ((1000 - 35) * outAmount_0p0001_zap / 1000) -// ); - -// assertEq(weth.balanceOf(address(zap)), 0); -// assertEq(usdc.balanceOf(address(zap)), 0); -// assertEq(usdx.balanceOf(address(zap)), 0); -// } - -// function testOdosSwapMedium_Success() public selectFork(FORK["1_zap"]) { -// address user = vm.addr(1); -// uint256 amount = 1e18; -// _spin(user, weth, amount); - -// uint256 wethBefore = weth.balanceOf(address(user)); -// uint256 usdcBefore = usdc.balanceOf(address(user)); - -// vm.startPrank(user); -// weth.approve(address(zap), amount); -// zap.swapFrom(address(weth), swapData_1_zap, amount, user); -// vm.stopPrank(); - -// assertEq(weth.balanceOf(address(user)), wethBefore - 1 ether); -// assertGt( -// usdc.balanceOf(address(user)), -// usdcBefore + ((1000 - 35) * outAmount_1_zap / 1000) -// ); - -// assertEq(weth.balanceOf(address(zap)), 0); -// assertEq(usdc.balanceOf(address(zap)), 0); -// assertEq(usdx.balanceOf(address(zap)), 0); -// } - -// function testOdosSwapLarge_Success() public selectFork(FORK["10_zap"]) { -// address user = vm.addr(1); -// uint256 amount = 120e18; -// _spin(user, weth, amount); - -// uint256 wethBefore = weth.balanceOf(address(user)); -// uint256 usdcBefore = usdc.balanceOf(address(user)); - -// vm.startPrank(user); -// weth.approve(address(zap), 100 ether); -// zap.swapFrom(address(weth), swapData_10_zap, 10 ether, user); -// vm.stopPrank(); - -// assertEq(weth.balanceOf(address(user)), wethBefore - 10 ether); -// assertGt( -// usdc.balanceOf(address(user)), -// usdcBefore + ((1000 - 35) * outAmount_10_zap / 1000) -// ); - -// assertEq(weth.balanceOf(address(zap)), 0); -// assertEq(usdc.balanceOf(address(zap)), 0); -// assertEq(usdx.balanceOf(address(zap)), 0); -// } - -// // this test fails because unspent input asset is not refunded -// function testOdosSwapRepeat_Success() public selectFork(FORK["1_zap"]) { -// // odos swap data can be repeated! -// address user = vm.addr(1); -// uint256 amount = 1e18; -// _spin(user, weth, amount * 2); - -// uint256 wethBefore = weth.balanceOf(address(user)); -// uint256 usdcBefore = usdc.balanceOf(address(user)); - -// vm.startPrank(user); -// weth.approve(address(zap), amount); -// zap.swapFrom(address(weth), swapData_1_zap, amount, user); -// vm.stopPrank(); - -// assertEq(weth.balanceOf(address(user)), wethBefore - 1 ether); -// assertGe( -// usdc.balanceOf(address(user)), -// usdcBefore + ((1000 - 10) * outAmount_1_zap / 1000) -// ); - -// assertEq(weth.balanceOf(address(zap)), 0); -// assertEq(usdc.balanceOf(address(zap)), 0); -// assertEq(usdx.balanceOf(address(zap)), 0); - -// vm.startPrank(user); -// weth.approve(address(zap), amount); -// zap.swapFrom(address(weth), swapData_1_zap, amount, user); -// vm.stopPrank(); - -// assertEq(weth.balanceOf(address(user)), wethBefore - 2 ether); -// assertGe( -// usdc.balanceOf(address(user)), -// usdcBefore + 2 * ((1000 - 10) * outAmount_1_zap / 1000) -// ); - -// assertEq(weth.balanceOf(address(zap)), 0); -// assertEq(usdc.balanceOf(address(zap)), 0); -// assertEq(usdx.balanceOf(address(zap)), 0); -// } - -// function testOdosSwapSendToWrongAddress_Fail() -// public -// selectFork(FORK["1_wrong"]) -// { -// // failing because slippage exceeded -// address user = vm.addr(1); -// uint256 amount = 1e18; -// _spin(user, weth, amount); - -// uint256 wethBefore = weth.balanceOf(address(user)); -// uint256 usdcBefore = usdc.balanceOf(address(user)); - -// vm.startPrank(user); -// weth.approve(address(zap), amount); - -// vm.expectRevert(bytes("ERC20: transfer amount exceeds balance")); -// zap.swapFrom(address(weth), swapData_1_wrong, amount, user); -// vm.stopPrank(); - -// assertEq(weth.balanceOf(address(user)), wethBefore); -// assertEq(usdc.balanceOf(address(user)), usdcBefore); - -// assertEq(weth.balanceOf(address(zap)), 0); -// assertEq(usdc.balanceOf(address(zap)), 0); -// assertEq(usdx.balanceOf(address(zap)), 0); -// } - -// function testOdosSwapSendToContract_Reentrancy_Success() -// public -// selectFork(FORK["10_attacker"]) -// { -// Attacker attackerContract = new Attacker(usdc, address(zap)); -// uint256 amountUsdc = 1 ether; // non-realistic amount of USDC, but it -// is -// // more to prove that the reentrancy is possible but not feasible -// or -// // exploitable -// address attacker = vm.addr(1234); - -// _spin(attacker, usdc, amountUsdc); - -// uint256 usdcBalBefore = usdc.balanceOf(attacker); -// uint256 ethBalBefore = address(attackerContract).balance; -// assertEq(ethBalBefore, 0); -// assertEq(usdcBalBefore, amountUsdc); - -// vm.startPrank(attacker); -// usdc.approve(address(zap), amountUsdc); -// zap.swapFrom(address(usdc), swapData_10_attacker, amountUsdc, -// attacker); -// vm.stopPrank(); - -// uint256 ethBalAfter = address(attackerContract).balance; -// uint256 usdcBalAfter = usdc.balanceOf(attacker); - -// assertGe( -// ethBalAfter, -// ethBalBefore + (1000 - 10) * outAmount_10_attacker / 1000 -// ); - -// uint256 unrefundedUsdcZap = usdc.balanceOf(address(zap)); -// assertEq(unrefundedUsdcZap, 0); -// // the final amounts are less than or equal to the amount provided -// // initially, ie no profit -// assertEq(usdcBalBefore, usdcBalAfter + inAmount_10_attacker); -// } - -// function testUnwindSmallDebtNoOI_Overpay_AccountOwner_Success() -// public -// selectFork(FORK["0p01_zap"]) -// { -// uint128 accountId = smallAccountIdNoOi; -// address accountOwner = smallAccountNoOiOwner; - -// uint256 tcvBefore = perpsMarket.totalCollateralValue(accountId); -// uint256 debt = perpsMarket.debt(accountId); -// uint256 collateralAmount = perpsMarket.getCollateralAmount(accountId, -// 4); -// uint256 wethBefore = weth.balanceOf(address(this)); -// uint256 usdcBefore = usdc.balanceOf(address(this)); - -// assertGt(tcvBefore, 0); -// assertGt(debt, 0); -// assertEq(perpsMarket.totalAccountOpenInterest(accountId), 0); - -// vm.startPrank(accountOwner); -// perpsMarket.grantPermission( -// accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) -// ); - -// zap.unwind( -// accountId, -// 4, // sETH collateral ID -// collateralAmount, -// address(weth), -// swapData_0p01_zap, -// 0, -// 0, -// 0.01 ether, -// address(this) -// ); -// vm.stopPrank(); - -// assertEq(perpsMarket.debt(accountId), 0); -// assertEq(perpsMarket.totalCollateralValue(accountId), 0); -// assertEq(perpsMarket.totalAccountOpenInterest(accountId), 0); -// assertFalse( -// perpsMarket.hasPermission( -// accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) -// ) -// ); - -// assertEq( -// weth.balanceOf(address(this)), -// wethBefore + collateralAmount - 0.01 ether -// ); -// assertGt( -// usdc.balanceOf(address(this)), -// usdcBefore + ((1000 - 35) * outAmount_0p01_zap / 1000) -// - (debt / 1e12) -// ); - -// assertEq(weth.balanceOf(address(zap)), 0); -// assertEq(usdc.balanceOf(address(zap)), 0); -// assertLt(usdx.balanceOf(address(zap)), 1 ether); -// } - -// function testUnwindSmallDebtWithOI_OverPay_AccountOwner_Success() -// public -// selectFork(FORK["0p01_zap"]) -// { -// uint128 accountId = smallAccountIdWithOi; -// address accountOwner = smallAccountWithOiOwner; - -// uint256 tcvBefore = perpsMarket.totalCollateralValue(accountId); -// uint256 debt = perpsMarket.debt(accountId); -// uint256 collateralAmount = perpsMarket.getCollateralAmount(accountId, -// 4); -// uint256 wethBefore = weth.balanceOf(address(this)); -// uint256 usdcBefore = usdc.balanceOf(address(this)); - -// assertGt(tcvBefore, 0); -// assertGt(debt, 0); -// assertGt(perpsMarket.totalAccountOpenInterest(accountId), 0); - -// vm.startPrank(accountOwner); -// perpsMarket.grantPermission( -// accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) -// ); - -// zap.unwind( -// accountId, -// 4, // sETH collateral ID -// 0.01 ether, -// address(weth), -// swapData_0p01_zap, -// 0, -// 0, -// 0.01 ether, -// address(this) -// ); -// vm.stopPrank(); - -// assertEq(perpsMarket.debt(accountId), 0); -// assertEq( -// perpsMarket.getCollateralAmount(accountId, 4), -// collateralAmount - 0.01 ether -// ); -// assertGt( -// perpsMarket.totalCollateralValue(accountId), -// tcvBefore - outValue_0p01_zap -// ); // this check is weak because the oracle price on this block is -// diff -// // from the odos api price -// assertGt(perpsMarket.totalAccountOpenInterest(accountId), 0); -// assertFalse( -// perpsMarket.hasPermission( -// accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) -// ) -// ); - -// assertEq(weth.balanceOf(address(this)), wethBefore); -// assertGt( -// usdc.balanceOf(address(this)), -// usdcBefore + ((1000 - 35) * outAmount_0p01_zap / 1000) -// - (debt / 1e12) -// ); - -// assertEq(weth.balanceOf(address(zap)), 0); -// assertEq(usdc.balanceOf(address(zap)), 0); -// assertLt(usdx.balanceOf(address(zap)), 1 ether); -// } - -// function testUnwindSmallDebtNoOI_Underpay_AccountOwner_Fail() -// public -// selectFork(FORK["0p001_zap"]) -// { -// uint128 accountId = smallAccountIdNoOi; -// address accountOwner = smallAccountNoOiOwner; - -// uint256 tcvBefore = perpsMarket.totalCollateralValue(accountId); -// uint256 debt = perpsMarket.debt(accountId); -// uint256 collateralAmount = perpsMarket.getCollateralAmount(accountId, -// 4); -// uint256 wethBefore = weth.balanceOf(address(this)); -// uint256 usdcBefore = usdc.balanceOf(address(this)); - -// assertGt(tcvBefore, 0); -// assertGt(debt, 0); -// assertEq(perpsMarket.totalAccountOpenInterest(accountId), 0); - -// vm.startPrank(accountOwner); -// perpsMarket.grantPermission( -// accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) -// ); - -// vm.expectRevert(bytes("ERC20: transfer amount exceeds balance")); -// zap.unwind( -// accountId, -// 4, // sETH collateral ID -// collateralAmount, -// address(weth), -// swapData_0p001_zap, -// 0, -// 0, -// 0.001 ether, -// address(this) -// ); -// vm.stopPrank(); - -// assertEq(perpsMarket.debt(accountId), debt); -// assertEq(perpsMarket.totalCollateralValue(accountId), tcvBefore); -// assertEq(perpsMarket.totalAccountOpenInterest(accountId), 0); -// assertTrue( -// perpsMarket.hasPermission( -// accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) -// ) -// ); - -// assertEq(weth.balanceOf(address(this)), wethBefore); -// assertEq(usdc.balanceOf(address(this)), usdcBefore); - -// assertEq(weth.balanceOf(address(zap)), 0); -// assertEq(usdc.balanceOf(address(zap)), 0); -// assertEq(usdx.balanceOf(address(zap)), 0); -// } - -// function -// testUnwindSmallDebtNoOI_Overpay_AccountOwner_OdosToWrongAddress_Fail( -// ) -// public -// selectFork(FORK["0p01_wrong"]) -// { -// uint128 accountId = smallAccountIdNoOi; -// address accountOwner = smallAccountNoOiOwner; - -// uint256 tcvBefore = perpsMarket.totalCollateralValue(accountId); -// uint256 debt = perpsMarket.debt(accountId); -// uint256 collateralAmount = perpsMarket.getCollateralAmount(accountId, -// 4); -// uint256 wethBefore = weth.balanceOf(address(this)); -// uint256 usdcBefore = usdc.balanceOf(address(this)); - -// assertGt(tcvBefore, 0); -// assertGt(debt, 0); -// assertEq(perpsMarket.totalAccountOpenInterest(accountId), 0); - -// vm.startPrank(accountOwner); -// perpsMarket.grantPermission( -// accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) -// ); - -// vm.expectRevert(bytes("ERC20: transfer amount exceeds balance")); -// zap.unwind( -// accountId, -// 4, // sETH collateral ID -// collateralAmount, -// address(weth), -// swapData_0p01_wrong, -// 0, -// 0, -// 0.01 ether, -// address(this) -// ); -// vm.stopPrank(); - -// assertEq(perpsMarket.debt(accountId), debt); -// assertEq(perpsMarket.totalCollateralValue(accountId), tcvBefore); -// assertEq(perpsMarket.totalAccountOpenInterest(accountId), 0); -// assertTrue( -// perpsMarket.hasPermission( -// accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) -// ) -// ); - -// assertEq(weth.balanceOf(address(this)), wethBefore); -// assertEq(usdc.balanceOf(address(this)), usdcBefore); - -// assertEq(weth.balanceOf(address(zap)), 0); -// assertEq(usdc.balanceOf(address(zap)), 0); -// assertEq(usdx.balanceOf(address(zap)), 0); -// } - -// error NotPermitted(); - -// function testUnwindSmallDebtNoOI_Overpay_NotAccountOwner_Fail() -// public -// selectFork(FORK["0p01_zap"]) -// { -// uint128 accountId = smallAccountIdNoOi; -// address accountOwner = smallAccountNoOiOwner; - -// uint256 tcvBefore = perpsMarket.totalCollateralValue(accountId); -// uint256 debt = perpsMarket.debt(accountId); -// uint256 collateralAmount = perpsMarket.getCollateralAmount(accountId, -// 4); -// uint256 wethBefore = weth.balanceOf(address(this)); -// uint256 usdcBefore = usdc.balanceOf(address(this)); - -// assertGt(tcvBefore, 0); -// assertGt(debt, 0); -// assertEq(perpsMarket.totalAccountOpenInterest(accountId), 0); - -// vm.startPrank(accountOwner); -// perpsMarket.grantPermission( -// accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) -// ); -// vm.stopPrank(); - -// vm.expectRevert(abi.encodeWithSelector(NotPermitted.selector)); -// zap.unwind( -// accountId, -// 4, -// collateralAmount, -// address(weth), -// swapData_0p001_zap, -// 0, -// 0, -// 0.001 ether, -// address(this) -// ); - -// assertEq(perpsMarket.debt(accountId), debt); -// assertEq(perpsMarket.totalCollateralValue(accountId), tcvBefore); -// assertEq(perpsMarket.totalAccountOpenInterest(accountId), 0); -// assertTrue( -// perpsMarket.hasPermission( -// accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) -// ) -// ); - -// assertEq(weth.balanceOf(address(this)), wethBefore); -// assertEq(usdc.balanceOf(address(this)), usdcBefore); - -// assertEq(weth.balanceOf(address(zap)), 0); -// assertEq(usdc.balanceOf(address(zap)), 0); -// assertEq(usdx.balanceOf(address(zap)), 0); -// } - -// function testUnwindSmallDebtNoOI_ZapNotPermitted_Fail() -// public -// selectFork(FORK["0p01_zap"]) -// { -// uint128 accountId = smallAccountIdNoOi; -// address accountOwner = smallAccountNoOiOwner; - -// uint256 tcvBefore = perpsMarket.totalCollateralValue(accountId); -// uint256 debt = perpsMarket.debt(accountId); -// uint256 collateralAmount = perpsMarket.getCollateralAmount(accountId, -// 4); -// uint256 wethBefore = weth.balanceOf(address(this)); -// uint256 usdcBefore = usdc.balanceOf(address(this)); - -// assertGt(tcvBefore, 0); -// assertGt(debt, 0); -// assertEq(perpsMarket.totalAccountOpenInterest(accountId), 0); - -// vm.startPrank(accountOwner); -// vm.expectRevert( -// abi.encodeWithSelector( -// IPerpsMarket.PermissionDenied.selector, -// 170_141_183_460_469_231_731_687_303_715_884_106_052, -// _PERPS_MODIFY_COLLATERAL_PERMISSION, -// 0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f -// ) -// ); -// zap.unwind( -// accountId, -// 4, -// collateralAmount, -// address(weth), -// swapData_0p001_zap, -// 0, -// 0, -// 0.001 ether, -// address(this) -// ); -// vm.stopPrank(); - -// assertEq(perpsMarket.debt(accountId), debt); -// assertEq(perpsMarket.totalCollateralValue(accountId), tcvBefore); -// assertEq(perpsMarket.totalAccountOpenInterest(accountId), 0); -// assertFalse( -// perpsMarket.hasPermission( -// accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) -// ) -// ); - -// assertEq(weth.balanceOf(address(this)), wethBefore); -// assertEq(usdc.balanceOf(address(this)), usdcBefore); - -// assertEq(weth.balanceOf(address(zap)), 0); -// assertEq(usdc.balanceOf(address(zap)), 0); -// assertEq(usdx.balanceOf(address(zap)), 0); -// } - -// error OnlyAave(address); - -// function testUnwindFailDirectCallback() -// public -// selectFork(FORK["0p01_zap"]) -// { -// vm.expectRevert( -// abi.encodeWithSelector(OnlyAave.selector, address(this)) -// ); -// zap.executeOperation(address(0), 0, 0, address(0), ""); -// } - -// error ReentrancyDetected(uint8, uint8); - -// function testUnwindFailDirectCallbackInvalidOrigin() -// public -// selectFork(FORK["0p01_zap"]) -// { -// vm.startPrank(BASE_AAVE_POOL); -// vm.expectRevert( -// abi.encodeWithSelector(ReentrancyDetected.selector, 0, 1) -// ); -// zap.executeOperation(address(0), 0, 0, address(0), ""); -// vm.stopPrank(); -// } - -// function testUnwindLargeDebtNoOI_Overpay_AccountOwner_Success() -// public -// selectFork(FORK["10_zap"]) -// { -// uint128 accountId = largeAccountIdNoOi; -// address accountOwner = largeAccountNoOiOwner; - -// uint256 tcvBefore = perpsMarket.totalCollateralValue(accountId); -// uint256 debt = perpsMarket.debt(accountId); -// uint256 collateralAmount = perpsMarket.getCollateralAmount(accountId, -// 4); -// uint256 wethBefore = weth.balanceOf(address(this)); -// uint256 usdcBefore = usdc.balanceOf(address(this)); - -// assertGt(tcvBefore, 0); -// assertGt(debt, 0); -// assertEq(perpsMarket.totalAccountOpenInterest(accountId), 0); - -// vm.startPrank(accountOwner); -// perpsMarket.grantPermission( -// accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) -// ); - -// zap.unwind( -// accountId, -// 4, // sETH collateral ID -// collateralAmount, -// address(weth), -// swapData_10_zap, -// 0, -// 0, -// 10 ether, -// address(this) -// ); -// vm.stopPrank(); - -// assertEq(perpsMarket.debt(accountId), 0); -// assertEq(perpsMarket.totalCollateralValue(accountId), 0); -// assertEq(perpsMarket.totalAccountOpenInterest(accountId), 0); -// assertFalse( -// perpsMarket.hasPermission( -// accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) -// ) -// ); - -// assertEq( -// weth.balanceOf(address(this)), -// wethBefore + collateralAmount - 10 ether -// ); -// assertGt( -// usdc.balanceOf(address(this)), -// usdcBefore + ((1000 - 2) * outAmount_10_zap / 1000) - (debt / -// 1e12) -// ); - -// assertEq(weth.balanceOf(address(zap)), 0); -// assertEq(usdc.balanceOf(address(zap)), 0); -// assertLt(usdx.balanceOf(address(zap)), 1 ether); -// } - -// function testUnwindLargeDebtWithOI_OverPay_AccountOwner_Success() -// public -// selectFork(FORK["10_zap"]) -// { -// uint128 accountId = largeAccountIdWithOi; -// address accountOwner = largeAccountWithOiOwner; - -// uint256 tcvBefore = perpsMarket.totalCollateralValue(accountId); -// uint256 debt = perpsMarket.debt(accountId); -// uint256 collateralAmount = perpsMarket.getCollateralAmount(accountId, -// 4); -// uint256 wethBefore = weth.balanceOf(address(this)); -// uint256 usdcBefore = usdc.balanceOf(address(this)); - -// assertGt(tcvBefore, 0); -// assertGt(debt, 0); -// assertGt(perpsMarket.totalAccountOpenInterest(accountId), 0); - -// vm.startPrank(accountOwner); -// perpsMarket.grantPermission( -// accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) -// ); - -// zap.unwind( -// accountId, -// 4, // sETH collateral ID -// 10 ether, -// address(weth), -// swapData_10_zap, -// 0, -// 0, -// 10 ether, -// address(this) -// ); -// vm.stopPrank(); - -// assertEq(perpsMarket.debt(accountId), 0); -// assertEq( -// perpsMarket.getCollateralAmount(accountId, 4), -// collateralAmount - 10 ether -// ); -// assertGt( -// perpsMarket.totalCollateralValue(accountId), -// tcvBefore - outValue_10_zap -// ); // this check is weak because the oracle price on this block is -// diff -// // from the odos api price -// assertGt(perpsMarket.totalAccountOpenInterest(accountId), 0); -// assertFalse( -// perpsMarket.hasPermission( -// accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) -// ) -// ); - -// assertEq(weth.balanceOf(address(this)), wethBefore); -// assertGt( -// usdc.balanceOf(address(this)), -// usdcBefore + ((1000 - 1) * outAmount_10_zap / 1000) - (debt / -// 1e12) -// ); - -// assertEq(weth.balanceOf(address(zap)), 0); -// assertEq(usdc.balanceOf(address(zap)), 0); -// assertLt(usdx.balanceOf(address(zap)), 1 ether); -// } - -// function testBurnSmallDebtNoOI_Exact_AccountOwner_Success() -// public -// selectFork(FORK["1_zap"]) -// { -// uint128 accountId = smallAccountIdNoOi; -// address accountOwner = smallAccountNoOiOwner; - -// // check account debt -// uint256 debt = perpsMarket.debt(accountId); - -// uint256 amount = debt; - -// _spin(accountOwner, usdx, amount); -// uint256 balanceBefore = usdx.balanceOf(accountOwner); - -// vm.startPrank(accountOwner); -// usdx.approve(address(zap), amount); -// zap.burn(amount, accountId); -// vm.stopPrank(); - -// assertEq(perpsMarket.debt(accountId), 0); -// assertEq(usdx.balanceOf(accountOwner), balanceBefore - debt); - -// assertEq(weth.balanceOf(address(zap)), 0); -// assertEq(usdc.balanceOf(address(zap)), 0); -// assertEq(usdx.balanceOf(address(zap)), 0); -// } - -// function testBurnSmallDebtNoOI_Exact_NotAccountOwner_Success() -// public -// selectFork(FORK["1_zap"]) -// { -// uint128 accountId = smallAccountIdNoOi; -// address user = vm.addr(1234); - -// // check account debt -// uint256 debt = perpsMarket.debt(accountId); - -// uint256 amount = debt; - -// _spin(user, usdx, amount); -// uint256 balanceBefore = usdx.balanceOf(user); - -// vm.startPrank(user); -// usdx.approve(address(zap), amount); -// zap.burn(amount, accountId); -// vm.stopPrank(); - -// assertEq(perpsMarket.debt(accountId), 0); -// assertEq(usdx.balanceOf(user), balanceBefore - debt); - -// assertEq(weth.balanceOf(address(zap)), 0); -// assertEq(usdc.balanceOf(address(zap)), 0); -// assertEq(usdx.balanceOf(address(zap)), 0); -// } - -// function testBurnSmallDebtNoOI_Overpay_AccountOwner_Success() -// public -// selectFork(FORK["1_zap"]) -// { -// uint128 accountId = smallAccountIdNoOi; -// address accountOwner = smallAccountNoOiOwner; - -// // check account debt -// uint256 debt = perpsMarket.debt(accountId); - -// uint256 amount = 123_456_789 + debt; - -// _spin(accountOwner, usdx, amount); -// uint256 balanceBefore = usdx.balanceOf(accountOwner); - -// vm.startPrank(accountOwner); -// usdx.approve(address(zap), amount); -// zap.burn(amount, accountId); -// vm.stopPrank(); - -// assertEq(perpsMarket.debt(accountId), 0); -// assertEq(usdx.balanceOf(accountOwner), balanceBefore - debt); -// assertEq(usdx.balanceOf(accountOwner), 123_456_789); - -// assertEq(weth.balanceOf(address(zap)), 0); -// assertEq(usdc.balanceOf(address(zap)), 0); -// assertEq(usdx.balanceOf(address(zap)), 0); -// } - -// function testBurnSmallDebtNoOI_Overpay_NotAccountOwner_Success() -// public -// selectFork(FORK["1_zap"]) -// { -// uint128 accountId = smallAccountIdNoOi; -// address user = vm.addr(1234); - -// // check account debt -// uint256 debt = perpsMarket.debt(accountId); +// / TODO add back this test + +// SPDX-License-Identifier: MIT +pragma solidity 0.8.27; + +import {Base} from "../script/utils/Parameters.sol"; +import {IERC20, Zap} from "../src/Zap.sol"; +import {Flush} from "../src/utils/Flush.sol"; +import "./interfaces/ISynthetix.sol"; + +import {Bootstrap} from "./utils/Bootstrap.sol"; +import {Constants} from "./utils/Constants.sol"; +import {OdosSwapData} from "./utils/OdosSwapData.sol"; +import "forge-std/Test.sol"; + +interface IPyth { + + struct PythPrice { + // Price + int64 price; + // Confidence interval around the price + uint64 conf; + // Price exponent + int32 expo; + // Unix timestamp describing when the price was published + uint256 publishTime; + } + + function getPriceUnsafe(bytes32 id) + external + view + returns (PythPrice memory price); + +} + +contract Attacker { + + IERC20 usdc; + address zap; + + constructor(IERC20 _usdc, address _zap) { + usdc = _usdc; + zap = _zap; + } + + function sweep(IERC20 token) public { + token.transfer(msg.sender, token.balanceOf(address(this))); + } + + receive() external payable { + // could call back into zap to do another swap but that just pays more + // fees, no real profit could transfer usdc into zap for zap to be able + // to pay back the original caller but that is also just shuffling your + // own assets around cant call reenter into executeOperation because of + // access controls + } + +} + +contract EndToEndTest is Test, Base, Constants, OdosSwapData { + + Zap zap; + + ISpotMarket spotMarket; + IPerpsMarket perpsMarket; + + IERC20 usdc; + IERC20 susdc; + IERC20 usdx; + IERC20 weth; + + uint128 smallAccountIdNoOi = + 170_141_183_460_469_231_731_687_303_715_884_106_052; + address smallAccountNoOiOwner = 0xbd400F9a17DC18bc031DBF5ffCD2689F4BF650dD; + + uint128 smallAccountIdWithOi = + 170_141_183_460_469_231_731_687_303_715_884_106_146; + address smallAccountWithOiOwner = 0x46232CbDB0512Ca7B00B8271e285BF8447F1330b; + + uint128 largeAccountIdNoOi = + 170_141_183_460_469_231_731_687_303_715_884_105_759; + address largeAccountNoOiOwner = 0x626a7d9f7bBCaEB1Fa88E8128Bec8f2Dd48b2b4d; + + uint128 largeAccountIdWithOi = + 170_141_183_460_469_231_731_687_303_715_884_105_846; + address largeAccountWithOiOwner = 0x1C1e747A6BE850549E9655addf59FD9e7cC2D4dC; + + string RPC = vm.envString("BASE_RPC"); + mapping(string => uint256) FORK; + + modifier selectFork(uint256 fork) { + initilizeFork(fork); + _; + } + + function setUp() public { + FORK["0p0001_wrong"] = vm.createFork(RPC, blockNumber_0p0001_wrong); + FORK["0p001_wrong"] = vm.createFork(RPC, blockNumber_0p001_wrong); + FORK["0p01_wrong"] = vm.createFork(RPC, blockNumber_0p01_wrong); + FORK["0p1_wrong"] = vm.createFork(RPC, blockNumber_0p1_wrong); + FORK["1_wrong"] = vm.createFork(RPC, blockNumber_1_wrong); + FORK["10_wrong"] = vm.createFork(RPC, blockNumber_10_wrong); + FORK["100_wrong"] = vm.createFork(RPC, blockNumber_100_wrong); + + FORK["0p0001_zap"] = vm.createFork(RPC, blockNumber_0p0001_zap); + FORK["0p001_zap"] = vm.createFork(RPC, blockNumber_0p001_zap); + FORK["0p01_zap"] = vm.createFork(RPC, blockNumber_0p01_zap); + FORK["0p1_zap"] = vm.createFork(RPC, blockNumber_0p1_zap); + FORK["1_zap"] = vm.createFork(RPC, blockNumber_1_zap); + FORK["10_zap"] = vm.createFork(RPC, blockNumber_10_zap); + FORK["100_zap"] = vm.createFork(RPC, blockNumber_100_zap); + + FORK["1000_attacker"] = vm.createFork(RPC, blockNumber_1000_attacker); + } + + function initilizeFork(uint256 fork) public { + vm.selectFork(fork); + + spotMarket = ISpotMarket(BASE_SPOT_MARKET); + perpsMarket = IPerpsMarket(BASE_PERPS_MARKET); + + usdc = IERC20(BASE_USDC); + usdx = IERC20(BASE_USDX); + weth = IERC20(BASE_WETH); + + uint128 synthMarketId = BASE_SUSDC_SPOT_MARKET_ID; + + susdc = IERC20(spotMarket.getSynth(synthMarketId)); + + // create Zap contract to use actual sUSDC synth + zap = new Zap({ + _usdc: address(usdc), + _usdx: address(usdx), + _sstata: address(0), // no stata on base + _spotMarket: address(spotMarket), + _perpsMarket: address(perpsMarket), + _referrer: BASE_REFERRER, + _susdcSpotId: synthMarketId, + _sstataSpotId: 0, // no stata on base + _aave: BASE_AAVE_POOL, + _stata: address(0), // no stata on base + _router: BASE_ROUTER + }); + + IPyth pyth = IPyth(0xd74CdD8Eef0E97a5a7678F907991316f88E7965A); + + vm.mockCall( + address(pyth), + abi.encodeWithSignature( + "getPriceUnsafe(bytes32)", + 0xeaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a + ), + abi.encode( + 99_990_737, + 105_741, + 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_928, + block.timestamp + ) + ); + vm.mockCall( + address(pyth), + abi.encodeWithSignature( + "getPriceUnsafe(bytes32)", + 0x6ec879b1e9963de5ee97e9c8710b742d6228252a5e2ca12d4ae81d7fe5ee8c5d + ), + abi.encode(99_874_029, 139_807, int32(-8), block.timestamp) + ); + vm.mockCall( + address(pyth), + abi.encodeWithSignature( + "getPriceUnsafe(bytes32)", + 0xff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace + ), + abi.encode(314_393_291_700, 176_780_592, int32(-8), block.timestamp) + ); + vm.mockCall( + address(pyth), + abi.encodeWithSignature( + "getPriceUnsafe(bytes32)", + 0xd69731a2e74ac1ce884fc3890f7ee324b6deb66147055249568869ed700882e4 + ), + abi.encode(191_914, 287, int32(-10), block.timestamp) + ); + vm.mockCall( + address(pyth), + abi.encodeWithSignature( + "getPriceUnsafe(bytes32)", + 0xe62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43 + ), + abi.encode( + 9_798_709_797_025, 5_649_852_176, int32(-8), block.timestamp + ) + ); + } + + function _spin(address eoa, IERC20 token, uint256 amount) internal { + vm.assume(amount > 0); + deal(address(token), eoa, amount); + } + + // this test fails because unspent input asses it not refunded + function testOdosSwapSmall_Success() + public + selectFork(FORK["0p0001_zap"]) + { + address user = vm.addr(1); + uint256 amount = 1e18; + _spin(user, weth, amount); + + uint256 wethBefore = weth.balanceOf(address(user)); + uint256 usdcBefore = usdc.balanceOf(address(user)); + + vm.startPrank(user); + weth.approve(address(zap), amount); + zap.swapFrom(address(weth), swapData_0p0001_zap, amount, user); + vm.stopPrank(); + + assertEq(weth.balanceOf(address(user)), wethBefore - 0.0001 ether); + assertGt( + usdc.balanceOf(address(user)), + usdcBefore + ((1000 - 35) * outAmount_0p0001_zap / 1000) + ); + + assertEq(weth.balanceOf(address(zap)), 0); + assertEq(usdc.balanceOf(address(zap)), 0); + assertEq(usdx.balanceOf(address(zap)), 0); + } + + function testOdosSwapMedium_Success() public selectFork(FORK["1_zap"]) { + address user = vm.addr(1); + uint256 amount = 1e18; + _spin(user, weth, amount); + + uint256 wethBefore = weth.balanceOf(address(user)); + uint256 usdcBefore = usdc.balanceOf(address(user)); + + vm.startPrank(user); + weth.approve(address(zap), amount); + zap.swapFrom(address(weth), swapData_1_zap, amount, user); + vm.stopPrank(); + + assertEq(weth.balanceOf(address(user)), wethBefore - 1 ether); + assertGt( + usdc.balanceOf(address(user)), + usdcBefore + ((1000 - 35) * outAmount_1_zap / 1000) + ); + + assertEq(weth.balanceOf(address(zap)), 0); + assertEq(usdc.balanceOf(address(zap)), 0); + assertEq(usdx.balanceOf(address(zap)), 0); + } + + function testOdosSwapLarge_Success() public selectFork(FORK["10_zap"]) { + address user = vm.addr(1); + uint256 amount = 120e18; + _spin(user, weth, amount); + + uint256 wethBefore = weth.balanceOf(address(user)); + uint256 usdcBefore = usdc.balanceOf(address(user)); + + vm.startPrank(user); + weth.approve(address(zap), 100 ether); + zap.swapFrom(address(weth), swapData_10_zap, 10 ether, user); + vm.stopPrank(); + + assertEq(weth.balanceOf(address(user)), wethBefore - 10 ether); + assertGt( + usdc.balanceOf(address(user)), + usdcBefore + ((1000 - 35) * outAmount_10_zap / 1000) + ); + + assertEq(weth.balanceOf(address(zap)), 0); + assertEq(usdc.balanceOf(address(zap)), 0); + assertEq(usdx.balanceOf(address(zap)), 0); + } + + // this test fails because unspent input asset is not refunded + function testOdosSwapRepeat_Success() public selectFork(FORK["1_zap"]) { + // odos swap data can be repeated! + address user = vm.addr(1); + uint256 amount = 1e18; + _spin(user, weth, amount * 2); + + uint256 wethBefore = weth.balanceOf(address(user)); + uint256 usdcBefore = usdc.balanceOf(address(user)); + + vm.startPrank(user); + weth.approve(address(zap), amount); + zap.swapFrom(address(weth), swapData_1_zap, amount, user); + vm.stopPrank(); + + assertEq(weth.balanceOf(address(user)), wethBefore - 1 ether); + assertGe( + usdc.balanceOf(address(user)), + usdcBefore + ((1000 - 10) * outAmount_1_zap / 1000) + ); + + assertEq(weth.balanceOf(address(zap)), 0); + assertEq(usdc.balanceOf(address(zap)), 0); + assertEq(usdx.balanceOf(address(zap)), 0); + + vm.startPrank(user); + weth.approve(address(zap), amount); + zap.swapFrom(address(weth), swapData_1_zap, amount, user); + vm.stopPrank(); + + assertEq(weth.balanceOf(address(user)), wethBefore - 2 ether); + assertGe( + usdc.balanceOf(address(user)), + usdcBefore + 2 * ((1000 - 10) * outAmount_1_zap / 1000) + ); + + assertEq(weth.balanceOf(address(zap)), 0); + assertEq(usdc.balanceOf(address(zap)), 0); + assertEq(usdx.balanceOf(address(zap)), 0); + } + + function testOdosSwapSendToWrongAddress_Fail() + public + selectFork(FORK["1_wrong"]) + { + // failing because slippage exceeded + address user = vm.addr(1); + uint256 amount = 1e18; + _spin(user, weth, amount); + + uint256 wethBefore = weth.balanceOf(address(user)); + uint256 usdcBefore = usdc.balanceOf(address(user)); + + vm.startPrank(user); + weth.approve(address(zap), amount); + + vm.expectRevert(bytes("ERC20: transfer amount exceeds balance")); + zap.swapFrom(address(weth), swapData_1_wrong, amount, user); + vm.stopPrank(); + + assertEq(weth.balanceOf(address(user)), wethBefore); + assertEq(usdc.balanceOf(address(user)), usdcBefore); + + assertEq(weth.balanceOf(address(zap)), 0); + assertEq(usdc.balanceOf(address(zap)), 0); + assertEq(usdx.balanceOf(address(zap)), 0); + } + + function testOdosSwapSendToContract_Reentrancy_Success() + public + selectFork(FORK["10_attacker"]) + { + Attacker attackerContract = new Attacker(usdc, address(zap)); + uint256 amountUsdc = 1 ether; // non-realistic amount of USDC, but it is + // more to prove that the reentrancy is possible but not feasible or + // exploitable + address attacker = vm.addr(1234); + + _spin(attacker, usdc, amountUsdc); + + uint256 usdcBalBefore = usdc.balanceOf(attacker); + uint256 ethBalBefore = address(attackerContract).balance; + assertEq(ethBalBefore, 0); + assertEq(usdcBalBefore, amountUsdc); + + vm.startPrank(attacker); + usdc.approve(address(zap), amountUsdc); + zap.swapFrom(address(usdc), swapData_10_attacker, amountUsdc, attacker); + vm.stopPrank(); + + uint256 ethBalAfter = address(attackerContract).balance; + uint256 usdcBalAfter = usdc.balanceOf(attacker); + + assertGe( + ethBalAfter, + ethBalBefore + (1000 - 10) * outAmount_10_attacker / 1000 + ); + + uint256 unrefundedUsdcZap = usdc.balanceOf(address(zap)); + assertEq(unrefundedUsdcZap, 0); + // the final amounts are less than or equal to the amount provided + // initially, ie no profit + assertEq(usdcBalBefore, usdcBalAfter + inAmount_10_attacker); + } + + function testUnwindSmallDebtNoOI_Overpay_AccountOwner_Success() + public + selectFork(FORK["0p01_zap"]) + { + uint128 accountId = smallAccountIdNoOi; + address accountOwner = smallAccountNoOiOwner; + + uint256 tcvBefore = perpsMarket.totalCollateralValue(accountId); + uint256 debt = perpsMarket.debt(accountId); + uint256 collateralAmount = perpsMarket.getCollateralAmount(accountId, 4); + uint256 wethBefore = weth.balanceOf(address(this)); + uint256 usdcBefore = usdc.balanceOf(address(this)); + + assertGt(tcvBefore, 0); + assertGt(debt, 0); + assertEq(perpsMarket.totalAccountOpenInterest(accountId), 0); + + vm.startPrank(accountOwner); + perpsMarket.grantPermission( + accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) + ); + + zap.unwind( + accountId, + 4, // sETH collateral ID + collateralAmount, + address(weth), + swapData_0p01_zap, + 0, + 0, + 0.01 ether, + address(this) + ); + vm.stopPrank(); + + assertEq(perpsMarket.debt(accountId), 0); + assertEq(perpsMarket.totalCollateralValue(accountId), 0); + assertEq(perpsMarket.totalAccountOpenInterest(accountId), 0); + assertFalse( + perpsMarket.hasPermission( + accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) + ) + ); + + assertEq( + weth.balanceOf(address(this)), + wethBefore + collateralAmount - 0.01 ether + ); + assertGt( + usdc.balanceOf(address(this)), + usdcBefore + ((1000 - 35) * outAmount_0p01_zap / 1000) + - (debt / 1e12) + ); + + assertEq(weth.balanceOf(address(zap)), 0); + assertEq(usdc.balanceOf(address(zap)), 0); + assertLt(usdx.balanceOf(address(zap)), 1 ether); + } + + function testUnwindSmallDebtWithOI_OverPay_AccountOwner_Success() + public + selectFork(FORK["0p01_zap"]) + { + uint128 accountId = smallAccountIdWithOi; + address accountOwner = smallAccountWithOiOwner; + + uint256 tcvBefore = perpsMarket.totalCollateralValue(accountId); + uint256 debt = perpsMarket.debt(accountId); + uint256 collateralAmount = perpsMarket.getCollateralAmount(accountId, 4); + uint256 wethBefore = weth.balanceOf(address(this)); + uint256 usdcBefore = usdc.balanceOf(address(this)); + + assertGt(tcvBefore, 0); + assertGt(debt, 0); + assertGt(perpsMarket.totalAccountOpenInterest(accountId), 0); + + vm.startPrank(accountOwner); + perpsMarket.grantPermission( + accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) + ); + + zap.unwind( + accountId, + 4, // sETH collateral ID + 0.01 ether, + address(weth), + swapData_0p01_zap, + 0, + 0, + 0.01 ether, + address(this) + ); + vm.stopPrank(); + + assertEq(perpsMarket.debt(accountId), 0); + assertEq( + perpsMarket.getCollateralAmount(accountId, 4), + collateralAmount - 0.01 ether + ); + assertGt( + perpsMarket.totalCollateralValue(accountId), + tcvBefore - outValue_0p01_zap + ); // this check is weak because the oracle price on this block is diff + // from the odos api price + assertGt(perpsMarket.totalAccountOpenInterest(accountId), 0); + assertFalse( + perpsMarket.hasPermission( + accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) + ) + ); + + assertEq(weth.balanceOf(address(this)), wethBefore); + assertGt( + usdc.balanceOf(address(this)), + usdcBefore + ((1000 - 35) * outAmount_0p01_zap / 1000) + - (debt / 1e12) + ); + + assertEq(weth.balanceOf(address(zap)), 0); + assertEq(usdc.balanceOf(address(zap)), 0); + assertLt(usdx.balanceOf(address(zap)), 1 ether); + } + + function testUnwindSmallDebtNoOI_Underpay_AccountOwner_Fail() + public + selectFork(FORK["0p001_zap"]) + { + uint128 accountId = smallAccountIdNoOi; + address accountOwner = smallAccountNoOiOwner; + + uint256 tcvBefore = perpsMarket.totalCollateralValue(accountId); + uint256 debt = perpsMarket.debt(accountId); + uint256 collateralAmount = perpsMarket.getCollateralAmount(accountId, 4); + uint256 wethBefore = weth.balanceOf(address(this)); + uint256 usdcBefore = usdc.balanceOf(address(this)); + + assertGt(tcvBefore, 0); + assertGt(debt, 0); + assertEq(perpsMarket.totalAccountOpenInterest(accountId), 0); + + vm.startPrank(accountOwner); + perpsMarket.grantPermission( + accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) + ); + + vm.expectRevert(bytes("ERC20: transfer amount exceeds balance")); + zap.unwind( + accountId, + 4, // sETH collateral ID + collateralAmount, + address(weth), + swapData_0p001_zap, + 0, + 0, + 0.001 ether, + address(this) + ); + vm.stopPrank(); + + assertEq(perpsMarket.debt(accountId), debt); + assertEq(perpsMarket.totalCollateralValue(accountId), tcvBefore); + assertEq(perpsMarket.totalAccountOpenInterest(accountId), 0); + assertTrue( + perpsMarket.hasPermission( + accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) + ) + ); + + assertEq(weth.balanceOf(address(this)), wethBefore); + assertEq(usdc.balanceOf(address(this)), usdcBefore); + + assertEq(weth.balanceOf(address(zap)), 0); + assertEq(usdc.balanceOf(address(zap)), 0); + assertEq(usdx.balanceOf(address(zap)), 0); + } + + function testUnwindSmallDebtNoOI_Overpay_AccountOwner_OdosToWrongAddress_Fail( + ) + public + selectFork(FORK["0p01_wrong"]) + { + uint128 accountId = smallAccountIdNoOi; + address accountOwner = smallAccountNoOiOwner; + + uint256 tcvBefore = perpsMarket.totalCollateralValue(accountId); + uint256 debt = perpsMarket.debt(accountId); + uint256 collateralAmount = perpsMarket.getCollateralAmount(accountId, 4); + uint256 wethBefore = weth.balanceOf(address(this)); + uint256 usdcBefore = usdc.balanceOf(address(this)); + + assertGt(tcvBefore, 0); + assertGt(debt, 0); + assertEq(perpsMarket.totalAccountOpenInterest(accountId), 0); + + vm.startPrank(accountOwner); + perpsMarket.grantPermission( + accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) + ); + + vm.expectRevert(bytes("ERC20: transfer amount exceeds balance")); + zap.unwind( + accountId, + 4, // sETH collateral ID + collateralAmount, + address(weth), + swapData_0p01_wrong, + 0, + 0, + 0.01 ether, + address(this) + ); + vm.stopPrank(); + + assertEq(perpsMarket.debt(accountId), debt); + assertEq(perpsMarket.totalCollateralValue(accountId), tcvBefore); + assertEq(perpsMarket.totalAccountOpenInterest(accountId), 0); + assertTrue( + perpsMarket.hasPermission( + accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) + ) + ); + + assertEq(weth.balanceOf(address(this)), wethBefore); + assertEq(usdc.balanceOf(address(this)), usdcBefore); + + assertEq(weth.balanceOf(address(zap)), 0); + assertEq(usdc.balanceOf(address(zap)), 0); + assertEq(usdx.balanceOf(address(zap)), 0); + } + + error NotPermitted(); + + function testUnwindSmallDebtNoOI_Overpay_NotAccountOwner_Fail() + public + selectFork(FORK["0p01_zap"]) + { + uint128 accountId = smallAccountIdNoOi; + address accountOwner = smallAccountNoOiOwner; + + uint256 tcvBefore = perpsMarket.totalCollateralValue(accountId); + uint256 debt = perpsMarket.debt(accountId); + uint256 collateralAmount = perpsMarket.getCollateralAmount(accountId, 4); + uint256 wethBefore = weth.balanceOf(address(this)); + uint256 usdcBefore = usdc.balanceOf(address(this)); + + assertGt(tcvBefore, 0); + assertGt(debt, 0); + assertEq(perpsMarket.totalAccountOpenInterest(accountId), 0); + + vm.startPrank(accountOwner); + perpsMarket.grantPermission( + accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) + ); + vm.stopPrank(); + + vm.expectRevert(abi.encodeWithSelector(NotPermitted.selector)); + zap.unwind( + accountId, + 4, + collateralAmount, + address(weth), + swapData_0p001_zap, + 0, + 0, + 0.001 ether, + address(this) + ); + + assertEq(perpsMarket.debt(accountId), debt); + assertEq(perpsMarket.totalCollateralValue(accountId), tcvBefore); + assertEq(perpsMarket.totalAccountOpenInterest(accountId), 0); + assertTrue( + perpsMarket.hasPermission( + accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) + ) + ); + + assertEq(weth.balanceOf(address(this)), wethBefore); + assertEq(usdc.balanceOf(address(this)), usdcBefore); + + assertEq(weth.balanceOf(address(zap)), 0); + assertEq(usdc.balanceOf(address(zap)), 0); + assertEq(usdx.balanceOf(address(zap)), 0); + } + + function testUnwindSmallDebtNoOI_ZapNotPermitted_Fail() + public + selectFork(FORK["0p01_zap"]) + { + uint128 accountId = smallAccountIdNoOi; + address accountOwner = smallAccountNoOiOwner; + + uint256 tcvBefore = perpsMarket.totalCollateralValue(accountId); + uint256 debt = perpsMarket.debt(accountId); + uint256 collateralAmount = perpsMarket.getCollateralAmount(accountId, 4); + uint256 wethBefore = weth.balanceOf(address(this)); + uint256 usdcBefore = usdc.balanceOf(address(this)); + + assertGt(tcvBefore, 0); + assertGt(debt, 0); + assertEq(perpsMarket.totalAccountOpenInterest(accountId), 0); + + vm.startPrank(accountOwner); + vm.expectRevert( + abi.encodeWithSelector( + IPerpsMarket.PermissionDenied.selector, + 170_141_183_460_469_231_731_687_303_715_884_106_052, + _PERPS_MODIFY_COLLATERAL_PERMISSION, + 0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f + ) + ); + zap.unwind( + accountId, + 4, + collateralAmount, + address(weth), + swapData_0p001_zap, + 0, + 0, + 0.001 ether, + address(this) + ); + vm.stopPrank(); + + assertEq(perpsMarket.debt(accountId), debt); + assertEq(perpsMarket.totalCollateralValue(accountId), tcvBefore); + assertEq(perpsMarket.totalAccountOpenInterest(accountId), 0); + assertFalse( + perpsMarket.hasPermission( + accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) + ) + ); + + assertEq(weth.balanceOf(address(this)), wethBefore); + assertEq(usdc.balanceOf(address(this)), usdcBefore); + + assertEq(weth.balanceOf(address(zap)), 0); + assertEq(usdc.balanceOf(address(zap)), 0); + assertEq(usdx.balanceOf(address(zap)), 0); + } + + error OnlyAave(address); + + function testUnwindFailDirectCallback() + public + selectFork(FORK["0p01_zap"]) + { + vm.expectRevert( + abi.encodeWithSelector(OnlyAave.selector, address(this)) + ); + zap.executeOperation(address(0), 0, 0, address(0), ""); + } + + error ReentrancyDetected(uint8, uint8); + + function testUnwindFailDirectCallbackInvalidOrigin() + public + selectFork(FORK["0p01_zap"]) + { + vm.startPrank(BASE_AAVE_POOL); + vm.expectRevert( + abi.encodeWithSelector(ReentrancyDetected.selector, 0, 1) + ); + zap.executeOperation(address(0), 0, 0, address(0), ""); + vm.stopPrank(); + } + + function testUnwindLargeDebtNoOI_Overpay_AccountOwner_Success() + public + selectFork(FORK["10_zap"]) + { + uint128 accountId = largeAccountIdNoOi; + address accountOwner = largeAccountNoOiOwner; + + uint256 tcvBefore = perpsMarket.totalCollateralValue(accountId); + uint256 debt = perpsMarket.debt(accountId); + uint256 collateralAmount = perpsMarket.getCollateralAmount(accountId, 4); + uint256 wethBefore = weth.balanceOf(address(this)); + uint256 usdcBefore = usdc.balanceOf(address(this)); + + assertGt(tcvBefore, 0); + assertGt(debt, 0); + assertEq(perpsMarket.totalAccountOpenInterest(accountId), 0); + + vm.startPrank(accountOwner); + perpsMarket.grantPermission( + accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) + ); + + zap.unwind( + accountId, + 4, // sETH collateral ID + collateralAmount, + address(weth), + swapData_10_zap, + 0, + 0, + 10 ether, + address(this) + ); + vm.stopPrank(); + + assertEq(perpsMarket.debt(accountId), 0); + assertEq(perpsMarket.totalCollateralValue(accountId), 0); + assertEq(perpsMarket.totalAccountOpenInterest(accountId), 0); + assertFalse( + perpsMarket.hasPermission( + accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) + ) + ); + + assertEq( + weth.balanceOf(address(this)), + wethBefore + collateralAmount - 10 ether + ); + assertGt( + usdc.balanceOf(address(this)), + usdcBefore + ((1000 - 2) * outAmount_10_zap / 1000) - (debt / 1e12) + ); + + assertEq(weth.balanceOf(address(zap)), 0); + assertEq(usdc.balanceOf(address(zap)), 0); + assertLt(usdx.balanceOf(address(zap)), 1 ether); + } + + function testUnwindLargeDebtWithOI_OverPay_AccountOwner_Success() + public + selectFork(FORK["10_zap"]) + { + uint128 accountId = largeAccountIdWithOi; + address accountOwner = largeAccountWithOiOwner; + + uint256 tcvBefore = perpsMarket.totalCollateralValue(accountId); + uint256 debt = perpsMarket.debt(accountId); + uint256 collateralAmount = perpsMarket.getCollateralAmount(accountId, 4); + uint256 wethBefore = weth.balanceOf(address(this)); + uint256 usdcBefore = usdc.balanceOf(address(this)); + + assertGt(tcvBefore, 0); + assertGt(debt, 0); + assertGt(perpsMarket.totalAccountOpenInterest(accountId), 0); + + vm.startPrank(accountOwner); + perpsMarket.grantPermission( + accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) + ); + + zap.unwind( + accountId, + 4, // sETH collateral ID + 10 ether, + address(weth), + swapData_10_zap, + 0, + 0, + 10 ether, + address(this) + ); + vm.stopPrank(); + + assertEq(perpsMarket.debt(accountId), 0); + assertEq( + perpsMarket.getCollateralAmount(accountId, 4), + collateralAmount - 10 ether + ); + assertGt( + perpsMarket.totalCollateralValue(accountId), + tcvBefore - outValue_10_zap + ); // this check is weak because the oracle price on this block is diff + // from the odos api price + assertGt(perpsMarket.totalAccountOpenInterest(accountId), 0); + assertFalse( + perpsMarket.hasPermission( + accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) + ) + ); + + assertEq(weth.balanceOf(address(this)), wethBefore); + assertGt( + usdc.balanceOf(address(this)), + usdcBefore + ((1000 - 1) * outAmount_10_zap / 1000) - (debt / 1e12) + ); + + assertEq(weth.balanceOf(address(zap)), 0); + assertEq(usdc.balanceOf(address(zap)), 0); + assertLt(usdx.balanceOf(address(zap)), 1 ether); + } + + function testBurnSmallDebtNoOI_Exact_AccountOwner_Success() + public + selectFork(FORK["1_zap"]) + { + uint128 accountId = smallAccountIdNoOi; + address accountOwner = smallAccountNoOiOwner; + + // check account debt + uint256 debt = perpsMarket.debt(accountId); + + uint256 amount = debt; + + _spin(accountOwner, usdx, amount); + uint256 balanceBefore = usdx.balanceOf(accountOwner); + + vm.startPrank(accountOwner); + usdx.approve(address(zap), amount); + zap.burn(amount, accountId); + vm.stopPrank(); + + assertEq(perpsMarket.debt(accountId), 0); + assertEq(usdx.balanceOf(accountOwner), balanceBefore - debt); + + assertEq(weth.balanceOf(address(zap)), 0); + assertEq(usdc.balanceOf(address(zap)), 0); + assertEq(usdx.balanceOf(address(zap)), 0); + } + + function testBurnSmallDebtNoOI_Exact_NotAccountOwner_Success() + public + selectFork(FORK["1_zap"]) + { + uint128 accountId = smallAccountIdNoOi; + address user = vm.addr(1234); + + // check account debt + uint256 debt = perpsMarket.debt(accountId); + + uint256 amount = debt; + + _spin(user, usdx, amount); + uint256 balanceBefore = usdx.balanceOf(user); + + vm.startPrank(user); + usdx.approve(address(zap), amount); + zap.burn(amount, accountId); + vm.stopPrank(); + + assertEq(perpsMarket.debt(accountId), 0); + assertEq(usdx.balanceOf(user), balanceBefore - debt); + + assertEq(weth.balanceOf(address(zap)), 0); + assertEq(usdc.balanceOf(address(zap)), 0); + assertEq(usdx.balanceOf(address(zap)), 0); + } + + function testBurnSmallDebtNoOI_Overpay_AccountOwner_Success() + public + selectFork(FORK["1_zap"]) + { + uint128 accountId = smallAccountIdNoOi; + address accountOwner = smallAccountNoOiOwner; + + // check account debt + uint256 debt = perpsMarket.debt(accountId); + + uint256 amount = 123_456_789 + debt; + + _spin(accountOwner, usdx, amount); + uint256 balanceBefore = usdx.balanceOf(accountOwner); + + vm.startPrank(accountOwner); + usdx.approve(address(zap), amount); + zap.burn(amount, accountId); + vm.stopPrank(); + + assertEq(perpsMarket.debt(accountId), 0); + assertEq(usdx.balanceOf(accountOwner), balanceBefore - debt); + assertEq(usdx.balanceOf(accountOwner), 123_456_789); + + assertEq(weth.balanceOf(address(zap)), 0); + assertEq(usdc.balanceOf(address(zap)), 0); + assertEq(usdx.balanceOf(address(zap)), 0); + } + + function testBurnSmallDebtNoOI_Overpay_NotAccountOwner_Success() + public + selectFork(FORK["1_zap"]) + { + uint128 accountId = smallAccountIdNoOi; + address user = vm.addr(1234); + + // check account debt + uint256 debt = perpsMarket.debt(accountId); -// uint256 amount = 123_456_789 + debt; - -// _spin(user, usdx, amount); -// uint256 balanceBefore = usdx.balanceOf(user); + uint256 amount = 123_456_789 + debt; + + _spin(user, usdx, amount); + uint256 balanceBefore = usdx.balanceOf(user); -// vm.startPrank(user); -// usdx.approve(address(zap), amount); -// zap.burn(amount, accountId); -// vm.stopPrank(); + vm.startPrank(user); + usdx.approve(address(zap), amount); + zap.burn(amount, accountId); + vm.stopPrank(); -// assertEq(perpsMarket.debt(accountId), 0); -// assertEq(usdx.balanceOf(user), balanceBefore - debt); -// assertEq(usdx.balanceOf(user), 123_456_789); + assertEq(perpsMarket.debt(accountId), 0); + assertEq(usdx.balanceOf(user), balanceBefore - debt); + assertEq(usdx.balanceOf(user), 123_456_789); -// assertEq(weth.balanceOf(address(zap)), 0); -// assertEq(usdc.balanceOf(address(zap)), 0); -// assertEq(usdx.balanceOf(address(zap)), 0); -// } + assertEq(weth.balanceOf(address(zap)), 0); + assertEq(usdc.balanceOf(address(zap)), 0); + assertEq(usdx.balanceOf(address(zap)), 0); + } -// function testBurnSmallDebtNoOI_Partial_AccountOwner_Success() -// public -// selectFork(FORK["1_zap"]) -// { -// uint128 accountId = smallAccountIdNoOi; -// address accountOwner = smallAccountNoOiOwner; + function testBurnSmallDebtNoOI_Partial_AccountOwner_Success() + public + selectFork(FORK["1_zap"]) + { + uint128 accountId = smallAccountIdNoOi; + address accountOwner = smallAccountNoOiOwner; -// // check account debt -// uint256 debt = perpsMarket.debt(accountId); - -// uint256 amount = debt - 1e6; + // check account debt + uint256 debt = perpsMarket.debt(accountId); + + uint256 amount = debt - 1e6; -// _spin(accountOwner, usdx, amount); -// uint256 balanceBefore = usdx.balanceOf(accountOwner); - -// vm.startPrank(accountOwner); -// usdx.approve(address(zap), amount); -// zap.burn(amount, accountId); -// vm.stopPrank(); + _spin(accountOwner, usdx, amount); + uint256 balanceBefore = usdx.balanceOf(accountOwner); + + vm.startPrank(accountOwner); + usdx.approve(address(zap), amount); + zap.burn(amount, accountId); + vm.stopPrank(); -// assertEq(perpsMarket.debt(accountId), debt - balanceBefore); -// assertEq(usdx.balanceOf(accountOwner), 0); + assertEq(perpsMarket.debt(accountId), debt - balanceBefore); + assertEq(usdx.balanceOf(accountOwner), 0); -// assertEq(weth.balanceOf(address(zap)), 0); -// assertEq(usdc.balanceOf(address(zap)), 0); -// assertEq(usdx.balanceOf(address(zap)), 0); -// } + assertEq(weth.balanceOf(address(zap)), 0); + assertEq(usdc.balanceOf(address(zap)), 0); + assertEq(usdx.balanceOf(address(zap)), 0); + } -// function testBurnSmallDebtNoOI_Partial_NotAccountOwner_Success() -// public -// selectFork(FORK["1_zap"]) -// { -// uint128 accountId = smallAccountIdNoOi; -// address user = vm.addr(1234); - -// // check account debt -// uint256 debt = perpsMarket.debt(accountId); - -// uint256 amount = debt - 1e6; - -// _spin(user, usdx, amount); -// uint256 balanceBefore = usdx.balanceOf(user); - -// vm.startPrank(user); -// usdx.approve(address(zap), amount); -// zap.burn(amount, accountId); -// vm.stopPrank(); + function testBurnSmallDebtNoOI_Partial_NotAccountOwner_Success() + public + selectFork(FORK["1_zap"]) + { + uint128 accountId = smallAccountIdNoOi; + address user = vm.addr(1234); + + // check account debt + uint256 debt = perpsMarket.debt(accountId); + + uint256 amount = debt - 1e6; + + _spin(user, usdx, amount); + uint256 balanceBefore = usdx.balanceOf(user); + + vm.startPrank(user); + usdx.approve(address(zap), amount); + zap.burn(amount, accountId); + vm.stopPrank(); -// assertEq(perpsMarket.debt(accountId), debt - balanceBefore); -// assertEq(usdx.balanceOf(user), 0); + assertEq(perpsMarket.debt(accountId), debt - balanceBefore); + assertEq(usdx.balanceOf(user), 0); -// assertEq(weth.balanceOf(address(zap)), 0); -// assertEq(usdc.balanceOf(address(zap)), 0); -// assertEq(usdx.balanceOf(address(zap)), 0); -// } + assertEq(weth.balanceOf(address(zap)), 0); + assertEq(usdc.balanceOf(address(zap)), 0); + assertEq(usdx.balanceOf(address(zap)), 0); + } -// function testBurnSmallDebtWithOI_Exact_AccountOwner_Success() -// public -// selectFork(FORK["1_zap"]) -// { -// uint128 accountId = smallAccountIdWithOi; -// address accountOwner = smallAccountWithOiOwner; - -// // check account debt -// uint256 debt = perpsMarket.debt(accountId); + function testBurnSmallDebtWithOI_Exact_AccountOwner_Success() + public + selectFork(FORK["1_zap"]) + { + uint128 accountId = smallAccountIdWithOi; + address accountOwner = smallAccountWithOiOwner; + + // check account debt + uint256 debt = perpsMarket.debt(accountId); -// uint256 amount = debt; - -// _spin(accountOwner, usdx, amount); -// uint256 balanceBefore = usdx.balanceOf(accountOwner); + uint256 amount = debt; + + _spin(accountOwner, usdx, amount); + uint256 balanceBefore = usdx.balanceOf(accountOwner); -// vm.startPrank(accountOwner); -// usdx.approve(address(zap), amount); -// zap.burn(amount, accountId); -// vm.stopPrank(); - -// assertEq(perpsMarket.debt(accountId), 0); -// assertEq(usdx.balanceOf(accountOwner), balanceBefore - debt); - -// assertEq(weth.balanceOf(address(zap)), 0); -// assertEq(usdc.balanceOf(address(zap)), 0); -// assertEq(usdx.balanceOf(address(zap)), 0); -// } - -// function testBurnSmallDebtWithOI_Exact_NotAccountOwner_Success() -// public -// selectFork(FORK["1_zap"]) -// { -// uint128 accountId = smallAccountIdWithOi; -// address user = vm.addr(1234); + vm.startPrank(accountOwner); + usdx.approve(address(zap), amount); + zap.burn(amount, accountId); + vm.stopPrank(); + + assertEq(perpsMarket.debt(accountId), 0); + assertEq(usdx.balanceOf(accountOwner), balanceBefore - debt); + + assertEq(weth.balanceOf(address(zap)), 0); + assertEq(usdc.balanceOf(address(zap)), 0); + assertEq(usdx.balanceOf(address(zap)), 0); + } + + function testBurnSmallDebtWithOI_Exact_NotAccountOwner_Success() + public + selectFork(FORK["1_zap"]) + { + uint128 accountId = smallAccountIdWithOi; + address user = vm.addr(1234); -// // check account debt -// uint256 debt = perpsMarket.debt(accountId); + // check account debt + uint256 debt = perpsMarket.debt(accountId); -// uint256 amount = debt; - -// _spin(user, usdx, amount); -// uint256 balanceBefore = usdx.balanceOf(user); + uint256 amount = debt; + + _spin(user, usdx, amount); + uint256 balanceBefore = usdx.balanceOf(user); -// vm.startPrank(user); -// usdx.approve(address(zap), amount); -// zap.burn(amount, accountId); -// vm.stopPrank(); - -// assertEq(perpsMarket.debt(accountId), 0); -// assertEq(usdx.balanceOf(user), balanceBefore - debt); + vm.startPrank(user); + usdx.approve(address(zap), amount); + zap.burn(amount, accountId); + vm.stopPrank(); + + assertEq(perpsMarket.debt(accountId), 0); + assertEq(usdx.balanceOf(user), balanceBefore - debt); -// assertEq(weth.balanceOf(address(zap)), 0); -// assertEq(usdc.balanceOf(address(zap)), 0); -// assertEq(usdx.balanceOf(address(zap)), 0); -// } + assertEq(weth.balanceOf(address(zap)), 0); + assertEq(usdc.balanceOf(address(zap)), 0); + assertEq(usdx.balanceOf(address(zap)), 0); + } -// function testBurnSmallDebtWithOI_Overpay_AccountOwner_Success() -// public -// selectFork(FORK["1_zap"]) -// { -// uint128 accountId = smallAccountIdWithOi; -// address accountOwner = smallAccountWithOiOwner; + function testBurnSmallDebtWithOI_Overpay_AccountOwner_Success() + public + selectFork(FORK["1_zap"]) + { + uint128 accountId = smallAccountIdWithOi; + address accountOwner = smallAccountWithOiOwner; -// // check account debt -// uint256 debt = perpsMarket.debt(accountId); + // check account debt + uint256 debt = perpsMarket.debt(accountId); -// uint256 amount = 123_456_789 + debt; - -// _spin(accountOwner, usdx, amount); -// uint256 balanceBefore = usdx.balanceOf(accountOwner); + uint256 amount = 123_456_789 + debt; + + _spin(accountOwner, usdx, amount); + uint256 balanceBefore = usdx.balanceOf(accountOwner); -// vm.startPrank(accountOwner); -// usdx.approve(address(zap), amount); -// zap.burn(amount, accountId); -// vm.stopPrank(); - -// assertEq(perpsMarket.debt(accountId), 0); -// assertEq(usdx.balanceOf(accountOwner), balanceBefore - debt); -// assertEq(usdx.balanceOf(accountOwner), 123_456_789); + vm.startPrank(accountOwner); + usdx.approve(address(zap), amount); + zap.burn(amount, accountId); + vm.stopPrank(); + + assertEq(perpsMarket.debt(accountId), 0); + assertEq(usdx.balanceOf(accountOwner), balanceBefore - debt); + assertEq(usdx.balanceOf(accountOwner), 123_456_789); -// assertEq(weth.balanceOf(address(zap)), 0); -// assertEq(usdc.balanceOf(address(zap)), 0); -// assertEq(usdx.balanceOf(address(zap)), 0); -// } + assertEq(weth.balanceOf(address(zap)), 0); + assertEq(usdc.balanceOf(address(zap)), 0); + assertEq(usdx.balanceOf(address(zap)), 0); + } -// function testBurnSmallDebtWithOI_Overpay_NotAccountOwner_Success() -// public -// selectFork(FORK["1_zap"]) -// { -// uint128 accountId = smallAccountIdWithOi; -// address user = vm.addr(1234); + function testBurnSmallDebtWithOI_Overpay_NotAccountOwner_Success() + public + selectFork(FORK["1_zap"]) + { + uint128 accountId = smallAccountIdWithOi; + address user = vm.addr(1234); -// // check account debt -// uint256 debt = perpsMarket.debt(accountId); + // check account debt + uint256 debt = perpsMarket.debt(accountId); -// uint256 amount = 123_456_789 + debt; - -// _spin(user, usdx, amount); -// uint256 balanceBefore = usdx.balanceOf(user); + uint256 amount = 123_456_789 + debt; + + _spin(user, usdx, amount); + uint256 balanceBefore = usdx.balanceOf(user); -// vm.startPrank(user); -// usdx.approve(address(zap), amount); -// zap.burn(amount, accountId); -// vm.stopPrank(); + vm.startPrank(user); + usdx.approve(address(zap), amount); + zap.burn(amount, accountId); + vm.stopPrank(); -// assertEq(perpsMarket.debt(accountId), 0); -// assertEq(usdx.balanceOf(user), balanceBefore - debt); -// assertEq(usdx.balanceOf(user), 123_456_789); + assertEq(perpsMarket.debt(accountId), 0); + assertEq(usdx.balanceOf(user), balanceBefore - debt); + assertEq(usdx.balanceOf(user), 123_456_789); -// assertEq(weth.balanceOf(address(zap)), 0); -// assertEq(usdc.balanceOf(address(zap)), 0); -// assertEq(usdx.balanceOf(address(zap)), 0); -// } + assertEq(weth.balanceOf(address(zap)), 0); + assertEq(usdc.balanceOf(address(zap)), 0); + assertEq(usdx.balanceOf(address(zap)), 0); + } -// function testBurnSmallDebtWithOI_Partial_AccountOwner_Success() -// public -// selectFork(FORK["1_zap"]) -// { -// uint128 accountId = smallAccountIdWithOi; -// address accountOwner = smallAccountWithOiOwner; + function testBurnSmallDebtWithOI_Partial_AccountOwner_Success() + public + selectFork(FORK["1_zap"]) + { + uint128 accountId = smallAccountIdWithOi; + address accountOwner = smallAccountWithOiOwner; -// // check account debt -// uint256 debt = perpsMarket.debt(accountId); - -// uint256 amount = debt - 1e6; + // check account debt + uint256 debt = perpsMarket.debt(accountId); + + uint256 amount = debt - 1e6; -// _spin(accountOwner, usdx, amount); -// uint256 balanceBefore = usdx.balanceOf(accountOwner); - -// vm.startPrank(accountOwner); -// usdx.approve(address(zap), amount); -// zap.burn(amount, accountId); -// vm.stopPrank(); + _spin(accountOwner, usdx, amount); + uint256 balanceBefore = usdx.balanceOf(accountOwner); + + vm.startPrank(accountOwner); + usdx.approve(address(zap), amount); + zap.burn(amount, accountId); + vm.stopPrank(); -// assertEq(perpsMarket.debt(accountId), debt - balanceBefore); -// assertEq(usdx.balanceOf(accountOwner), 0); + assertEq(perpsMarket.debt(accountId), debt - balanceBefore); + assertEq(usdx.balanceOf(accountOwner), 0); -// assertEq(weth.balanceOf(address(zap)), 0); -// assertEq(usdc.balanceOf(address(zap)), 0); -// assertEq(usdx.balanceOf(address(zap)), 0); -// } + assertEq(weth.balanceOf(address(zap)), 0); + assertEq(usdc.balanceOf(address(zap)), 0); + assertEq(usdx.balanceOf(address(zap)), 0); + } -// function testBurnSmallDebtWithOI_Partial_NotAccountOwner_Success() -// public -// selectFork(FORK["1_zap"]) -// { -// uint128 accountId = smallAccountIdWithOi; -// address user = vm.addr(1234); - -// // check account debt -// uint256 debt = perpsMarket.debt(accountId); - -// uint256 amount = debt - 1e6; - -// _spin(user, usdx, amount); -// uint256 balanceBefore = usdx.balanceOf(user); - -// vm.startPrank(user); -// usdx.approve(address(zap), amount); -// zap.burn(amount, accountId); -// vm.stopPrank(); + function testBurnSmallDebtWithOI_Partial_NotAccountOwner_Success() + public + selectFork(FORK["1_zap"]) + { + uint128 accountId = smallAccountIdWithOi; + address user = vm.addr(1234); + + // check account debt + uint256 debt = perpsMarket.debt(accountId); + + uint256 amount = debt - 1e6; + + _spin(user, usdx, amount); + uint256 balanceBefore = usdx.balanceOf(user); + + vm.startPrank(user); + usdx.approve(address(zap), amount); + zap.burn(amount, accountId); + vm.stopPrank(); -// assertEq(perpsMarket.debt(accountId), debt - balanceBefore); -// assertEq(usdx.balanceOf(user), 0); + assertEq(perpsMarket.debt(accountId), debt - balanceBefore); + assertEq(usdx.balanceOf(user), 0); -// assertEq(weth.balanceOf(address(zap)), 0); -// assertEq(usdc.balanceOf(address(zap)), 0); -// assertEq(usdx.balanceOf(address(zap)), 0); -// } + assertEq(weth.balanceOf(address(zap)), 0); + assertEq(usdc.balanceOf(address(zap)), 0); + assertEq(usdx.balanceOf(address(zap)), 0); + } -// function testBurnLargeDebtNoOI_Exact_AccountOwner_Success() -// public -// selectFork(FORK["1_zap"]) -// { -// uint128 accountId = largeAccountIdNoOi; -// address accountOwner = largeAccountNoOiOwner; - -// // check account debt -// uint256 debt = perpsMarket.debt(accountId); + function testBurnLargeDebtNoOI_Exact_AccountOwner_Success() + public + selectFork(FORK["1_zap"]) + { + uint128 accountId = largeAccountIdNoOi; + address accountOwner = largeAccountNoOiOwner; + + // check account debt + uint256 debt = perpsMarket.debt(accountId); -// uint256 amount = debt; - -// _spin(accountOwner, usdx, amount); -// uint256 balanceBefore = usdx.balanceOf(accountOwner); + uint256 amount = debt; + + _spin(accountOwner, usdx, amount); + uint256 balanceBefore = usdx.balanceOf(accountOwner); -// vm.startPrank(accountOwner); -// usdx.approve(address(zap), amount); -// zap.burn(amount, accountId); -// vm.stopPrank(); - -// assertEq(perpsMarket.debt(accountId), 0); -// assertEq(usdx.balanceOf(accountOwner), balanceBefore - debt); - -// assertEq(weth.balanceOf(address(zap)), 0); -// assertEq(usdc.balanceOf(address(zap)), 0); -// assertEq(usdx.balanceOf(address(zap)), 0); -// } - -// function testBurnLargeDebtNoOI_Exact_NotAccountOwner_Success() -// public -// selectFork(FORK["1_zap"]) -// { -// uint128 accountId = largeAccountIdNoOi; -// address user = vm.addr(1234); + vm.startPrank(accountOwner); + usdx.approve(address(zap), amount); + zap.burn(amount, accountId); + vm.stopPrank(); + + assertEq(perpsMarket.debt(accountId), 0); + assertEq(usdx.balanceOf(accountOwner), balanceBefore - debt); + + assertEq(weth.balanceOf(address(zap)), 0); + assertEq(usdc.balanceOf(address(zap)), 0); + assertEq(usdx.balanceOf(address(zap)), 0); + } + + function testBurnLargeDebtNoOI_Exact_NotAccountOwner_Success() + public + selectFork(FORK["1_zap"]) + { + uint128 accountId = largeAccountIdNoOi; + address user = vm.addr(1234); -// // check account debt -// uint256 debt = perpsMarket.debt(accountId); + // check account debt + uint256 debt = perpsMarket.debt(accountId); -// uint256 amount = debt; - -// _spin(user, usdx, amount); -// uint256 balanceBefore = usdx.balanceOf(user); + uint256 amount = debt; + + _spin(user, usdx, amount); + uint256 balanceBefore = usdx.balanceOf(user); -// vm.startPrank(user); -// usdx.approve(address(zap), amount); -// zap.burn(amount, accountId); -// vm.stopPrank(); - -// assertEq(perpsMarket.debt(accountId), 0); -// assertEq(usdx.balanceOf(user), balanceBefore - debt); + vm.startPrank(user); + usdx.approve(address(zap), amount); + zap.burn(amount, accountId); + vm.stopPrank(); + + assertEq(perpsMarket.debt(accountId), 0); + assertEq(usdx.balanceOf(user), balanceBefore - debt); -// assertEq(weth.balanceOf(address(zap)), 0); -// assertEq(usdc.balanceOf(address(zap)), 0); -// assertEq(usdx.balanceOf(address(zap)), 0); -// } + assertEq(weth.balanceOf(address(zap)), 0); + assertEq(usdc.balanceOf(address(zap)), 0); + assertEq(usdx.balanceOf(address(zap)), 0); + } -// function testBurnLargeDebtNoOI_Overpay_AccountOwner_Success() -// public -// selectFork(FORK["1_zap"]) -// { -// uint128 accountId = largeAccountIdNoOi; -// address accountOwner = largeAccountNoOiOwner; + function testBurnLargeDebtNoOI_Overpay_AccountOwner_Success() + public + selectFork(FORK["1_zap"]) + { + uint128 accountId = largeAccountIdNoOi; + address accountOwner = largeAccountNoOiOwner; -// // check account debt -// uint256 debt = perpsMarket.debt(accountId); + // check account debt + uint256 debt = perpsMarket.debt(accountId); -// uint256 amount = 123_456_789 + debt; - -// _spin(accountOwner, usdx, amount); -// uint256 balanceBefore = usdx.balanceOf(accountOwner); + uint256 amount = 123_456_789 + debt; + + _spin(accountOwner, usdx, amount); + uint256 balanceBefore = usdx.balanceOf(accountOwner); -// vm.startPrank(accountOwner); -// usdx.approve(address(zap), amount); -// zap.burn(amount, accountId); -// vm.stopPrank(); - -// assertEq(perpsMarket.debt(accountId), 0); -// assertEq(usdx.balanceOf(accountOwner), balanceBefore - debt); -// assertEq(usdx.balanceOf(accountOwner), 123_456_789); + vm.startPrank(accountOwner); + usdx.approve(address(zap), amount); + zap.burn(amount, accountId); + vm.stopPrank(); + + assertEq(perpsMarket.debt(accountId), 0); + assertEq(usdx.balanceOf(accountOwner), balanceBefore - debt); + assertEq(usdx.balanceOf(accountOwner), 123_456_789); -// assertEq(weth.balanceOf(address(zap)), 0); -// assertEq(usdc.balanceOf(address(zap)), 0); -// assertEq(usdx.balanceOf(address(zap)), 0); -// } + assertEq(weth.balanceOf(address(zap)), 0); + assertEq(usdc.balanceOf(address(zap)), 0); + assertEq(usdx.balanceOf(address(zap)), 0); + } -// function testBurnLargeDebtNoOI_Overpay_NotAccountOwner_Success() -// public -// selectFork(FORK["1_zap"]) -// { -// uint128 accountId = largeAccountIdNoOi; -// address user = vm.addr(1234); + function testBurnLargeDebtNoOI_Overpay_NotAccountOwner_Success() + public + selectFork(FORK["1_zap"]) + { + uint128 accountId = largeAccountIdNoOi; + address user = vm.addr(1234); -// // check account debt -// uint256 debt = perpsMarket.debt(accountId); + // check account debt + uint256 debt = perpsMarket.debt(accountId); -// uint256 amount = 123_456_789 + debt; - -// _spin(user, usdx, amount); -// uint256 balanceBefore = usdx.balanceOf(user); + uint256 amount = 123_456_789 + debt; + + _spin(user, usdx, amount); + uint256 balanceBefore = usdx.balanceOf(user); -// vm.startPrank(user); -// usdx.approve(address(zap), amount); -// zap.burn(amount, accountId); -// vm.stopPrank(); + vm.startPrank(user); + usdx.approve(address(zap), amount); + zap.burn(amount, accountId); + vm.stopPrank(); -// assertEq(perpsMarket.debt(accountId), 0); -// assertEq(usdx.balanceOf(user), balanceBefore - debt); -// assertEq(usdx.balanceOf(user), 123_456_789); + assertEq(perpsMarket.debt(accountId), 0); + assertEq(usdx.balanceOf(user), balanceBefore - debt); + assertEq(usdx.balanceOf(user), 123_456_789); -// assertEq(weth.balanceOf(address(zap)), 0); -// assertEq(usdc.balanceOf(address(zap)), 0); -// assertEq(usdx.balanceOf(address(zap)), 0); -// } + assertEq(weth.balanceOf(address(zap)), 0); + assertEq(usdc.balanceOf(address(zap)), 0); + assertEq(usdx.balanceOf(address(zap)), 0); + } -// function testBurnLargeDebtNoOI_Partial_AccountOwner_Success() -// public -// selectFork(FORK["1_zap"]) -// { -// uint128 accountId = largeAccountIdNoOi; -// address accountOwner = largeAccountNoOiOwner; + function testBurnLargeDebtNoOI_Partial_AccountOwner_Success() + public + selectFork(FORK["1_zap"]) + { + uint128 accountId = largeAccountIdNoOi; + address accountOwner = largeAccountNoOiOwner; -// // check account debt -// uint256 debt = perpsMarket.debt(accountId); - -// uint256 amount = debt - 1e6; + // check account debt + uint256 debt = perpsMarket.debt(accountId); + + uint256 amount = debt - 1e6; -// _spin(accountOwner, usdx, amount); -// uint256 balanceBefore = usdx.balanceOf(accountOwner); - -// vm.startPrank(accountOwner); -// usdx.approve(address(zap), amount); -// zap.burn(amount, accountId); -// vm.stopPrank(); + _spin(accountOwner, usdx, amount); + uint256 balanceBefore = usdx.balanceOf(accountOwner); + + vm.startPrank(accountOwner); + usdx.approve(address(zap), amount); + zap.burn(amount, accountId); + vm.stopPrank(); -// assertEq(perpsMarket.debt(accountId), debt - balanceBefore); -// assertEq(usdx.balanceOf(accountOwner), 0); + assertEq(perpsMarket.debt(accountId), debt - balanceBefore); + assertEq(usdx.balanceOf(accountOwner), 0); -// assertEq(weth.balanceOf(address(zap)), 0); -// assertEq(usdc.balanceOf(address(zap)), 0); -// assertEq(usdx.balanceOf(address(zap)), 0); -// } + assertEq(weth.balanceOf(address(zap)), 0); + assertEq(usdc.balanceOf(address(zap)), 0); + assertEq(usdx.balanceOf(address(zap)), 0); + } -// function testBurnLargeDebtNoOI_Partial_NotAccountOwner_Success() -// public -// selectFork(FORK["1_zap"]) -// { -// uint128 accountId = largeAccountIdNoOi; -// address user = vm.addr(1234); - -// // check account debt -// uint256 debt = perpsMarket.debt(accountId); - -// uint256 amount = debt - 1e6; - -// _spin(user, usdx, amount); -// uint256 balanceBefore = usdx.balanceOf(user); - -// vm.startPrank(user); -// usdx.approve(address(zap), amount); -// zap.burn(amount, accountId); -// vm.stopPrank(); + function testBurnLargeDebtNoOI_Partial_NotAccountOwner_Success() + public + selectFork(FORK["1_zap"]) + { + uint128 accountId = largeAccountIdNoOi; + address user = vm.addr(1234); + + // check account debt + uint256 debt = perpsMarket.debt(accountId); + + uint256 amount = debt - 1e6; + + _spin(user, usdx, amount); + uint256 balanceBefore = usdx.balanceOf(user); + + vm.startPrank(user); + usdx.approve(address(zap), amount); + zap.burn(amount, accountId); + vm.stopPrank(); -// assertEq(perpsMarket.debt(accountId), debt - balanceBefore); -// assertEq(usdx.balanceOf(user), 0); + assertEq(perpsMarket.debt(accountId), debt - balanceBefore); + assertEq(usdx.balanceOf(user), 0); -// assertEq(weth.balanceOf(address(zap)), 0); -// assertEq(usdc.balanceOf(address(zap)), 0); -// assertEq(usdx.balanceOf(address(zap)), 0); -// } + assertEq(weth.balanceOf(address(zap)), 0); + assertEq(usdc.balanceOf(address(zap)), 0); + assertEq(usdx.balanceOf(address(zap)), 0); + } -// function testBurnLargeDebtWithOI_Exact_AccountOwner_Success() -// public -// selectFork(FORK["1_zap"]) -// { -// uint128 accountId = largeAccountIdWithOi; -// address accountOwner = largeAccountWithOiOwner; - -// // check account debt -// uint256 debt = perpsMarket.debt(accountId); + function testBurnLargeDebtWithOI_Exact_AccountOwner_Success() + public + selectFork(FORK["1_zap"]) + { + uint128 accountId = largeAccountIdWithOi; + address accountOwner = largeAccountWithOiOwner; + + // check account debt + uint256 debt = perpsMarket.debt(accountId); -// uint256 amount = debt; - -// _spin(accountOwner, usdx, amount); -// uint256 balanceBefore = usdx.balanceOf(accountOwner); + uint256 amount = debt; + + _spin(accountOwner, usdx, amount); + uint256 balanceBefore = usdx.balanceOf(accountOwner); -// vm.startPrank(accountOwner); -// usdx.approve(address(zap), amount); -// zap.burn(amount, accountId); -// vm.stopPrank(); - -// assertEq(perpsMarket.debt(accountId), 0); -// assertEq(usdx.balanceOf(accountOwner), balanceBefore - debt); - -// assertEq(weth.balanceOf(address(zap)), 0); -// assertEq(usdc.balanceOf(address(zap)), 0); -// assertEq(usdx.balanceOf(address(zap)), 0); -// } - -// function testBurnLargeDebtWithOI_Exact_NotAccountOwner_Success() -// public -// selectFork(FORK["1_zap"]) -// { -// uint128 accountId = largeAccountIdWithOi; -// address user = vm.addr(1234); + vm.startPrank(accountOwner); + usdx.approve(address(zap), amount); + zap.burn(amount, accountId); + vm.stopPrank(); + + assertEq(perpsMarket.debt(accountId), 0); + assertEq(usdx.balanceOf(accountOwner), balanceBefore - debt); + + assertEq(weth.balanceOf(address(zap)), 0); + assertEq(usdc.balanceOf(address(zap)), 0); + assertEq(usdx.balanceOf(address(zap)), 0); + } + + function testBurnLargeDebtWithOI_Exact_NotAccountOwner_Success() + public + selectFork(FORK["1_zap"]) + { + uint128 accountId = largeAccountIdWithOi; + address user = vm.addr(1234); -// // check account debt -// uint256 debt = perpsMarket.debt(accountId); + // check account debt + uint256 debt = perpsMarket.debt(accountId); -// uint256 amount = debt; - -// _spin(user, usdx, amount); -// uint256 balanceBefore = usdx.balanceOf(user); + uint256 amount = debt; + + _spin(user, usdx, amount); + uint256 balanceBefore = usdx.balanceOf(user); -// vm.startPrank(user); -// usdx.approve(address(zap), amount); -// zap.burn(amount, accountId); -// vm.stopPrank(); - -// assertEq(perpsMarket.debt(accountId), 0); -// assertEq(usdx.balanceOf(user), balanceBefore - debt); + vm.startPrank(user); + usdx.approve(address(zap), amount); + zap.burn(amount, accountId); + vm.stopPrank(); + + assertEq(perpsMarket.debt(accountId), 0); + assertEq(usdx.balanceOf(user), balanceBefore - debt); -// assertEq(weth.balanceOf(address(zap)), 0); -// assertEq(usdc.balanceOf(address(zap)), 0); -// assertEq(usdx.balanceOf(address(zap)), 0); -// } + assertEq(weth.balanceOf(address(zap)), 0); + assertEq(usdc.balanceOf(address(zap)), 0); + assertEq(usdx.balanceOf(address(zap)), 0); + } -// function testBurnLargeDebtWithOI_Overpay_AccountOwner_Success() -// public -// selectFork(FORK["1_zap"]) -// { -// uint128 accountId = largeAccountIdWithOi; -// address accountOwner = largeAccountWithOiOwner; + function testBurnLargeDebtWithOI_Overpay_AccountOwner_Success() + public + selectFork(FORK["1_zap"]) + { + uint128 accountId = largeAccountIdWithOi; + address accountOwner = largeAccountWithOiOwner; -// // check account debt -// uint256 debt = perpsMarket.debt(accountId); + // check account debt + uint256 debt = perpsMarket.debt(accountId); -// uint256 amount = 123_456_789 + debt; - -// _spin(accountOwner, usdx, amount); -// uint256 balanceBefore = usdx.balanceOf(accountOwner); + uint256 amount = 123_456_789 + debt; + + _spin(accountOwner, usdx, amount); + uint256 balanceBefore = usdx.balanceOf(accountOwner); -// vm.startPrank(accountOwner); -// usdx.approve(address(zap), amount); -// zap.burn(amount, accountId); -// vm.stopPrank(); + vm.startPrank(accountOwner); + usdx.approve(address(zap), amount); + zap.burn(amount, accountId); + vm.stopPrank(); -// assertEq(perpsMarket.debt(accountId), 0); -// assertEq(usdx.balanceOf(accountOwner), balanceBefore - debt); -// assertEq(usdx.balanceOf(accountOwner), 123_456_789); + assertEq(perpsMarket.debt(accountId), 0); + assertEq(usdx.balanceOf(accountOwner), balanceBefore - debt); + assertEq(usdx.balanceOf(accountOwner), 123_456_789); -// assertEq(weth.balanceOf(address(zap)), 0); -// assertEq(usdc.balanceOf(address(zap)), 0); -// assertEq(usdx.balanceOf(address(zap)), 0); -// } + assertEq(weth.balanceOf(address(zap)), 0); + assertEq(usdc.balanceOf(address(zap)), 0); + assertEq(usdx.balanceOf(address(zap)), 0); + } -// function testBurnLargeDebtWithOI_Overpay_NotAccountOwner_Success() -// public -// selectFork(FORK["1_zap"]) -// { -// uint128 accountId = largeAccountIdWithOi; -// address user = vm.addr(1234); + function testBurnLargeDebtWithOI_Overpay_NotAccountOwner_Success() + public + selectFork(FORK["1_zap"]) + { + uint128 accountId = largeAccountIdWithOi; + address user = vm.addr(1234); -// // check account debt -// uint256 debt = perpsMarket.debt(accountId); + // check account debt + uint256 debt = perpsMarket.debt(accountId); -// uint256 amount = 123_456_789 + debt; + uint256 amount = 123_456_789 + debt; -// _spin(user, usdx, amount); -// uint256 balanceBefore = usdx.balanceOf(user); + _spin(user, usdx, amount); + uint256 balanceBefore = usdx.balanceOf(user); -// vm.startPrank(user); -// usdx.approve(address(zap), amount); -// zap.burn(amount, accountId); -// vm.stopPrank(); + vm.startPrank(user); + usdx.approve(address(zap), amount); + zap.burn(amount, accountId); + vm.stopPrank(); -// assertEq(perpsMarket.debt(accountId), 0); -// assertEq(usdx.balanceOf(user), balanceBefore - debt); -// assertEq(usdx.balanceOf(user), 123_456_789); + assertEq(perpsMarket.debt(accountId), 0); + assertEq(usdx.balanceOf(user), balanceBefore - debt); + assertEq(usdx.balanceOf(user), 123_456_789); -// assertEq(weth.balanceOf(address(zap)), 0); -// assertEq(usdc.balanceOf(address(zap)), 0); -// assertEq(usdx.balanceOf(address(zap)), 0); -// } + assertEq(weth.balanceOf(address(zap)), 0); + assertEq(usdc.balanceOf(address(zap)), 0); + assertEq(usdx.balanceOf(address(zap)), 0); + } -// function testBurnLargeDebtWithOI_Partial_AccountOwner_Success() -// public -// selectFork(FORK["1_zap"]) -// { -// uint128 accountId = largeAccountIdWithOi; -// address accountOwner = largeAccountWithOiOwner; + function testBurnLargeDebtWithOI_Partial_AccountOwner_Success() + public + selectFork(FORK["1_zap"]) + { + uint128 accountId = largeAccountIdWithOi; + address accountOwner = largeAccountWithOiOwner; -// // check account debt -// uint256 debt = perpsMarket.debt(accountId); + // check account debt + uint256 debt = perpsMarket.debt(accountId); -// uint256 amount = debt - 1e6; + uint256 amount = debt - 1e6; -// _spin(accountOwner, usdx, amount); -// uint256 balanceBefore = usdx.balanceOf(accountOwner); + _spin(accountOwner, usdx, amount); + uint256 balanceBefore = usdx.balanceOf(accountOwner); -// vm.startPrank(accountOwner); -// usdx.approve(address(zap), amount); -// zap.burn(amount, accountId); -// vm.stopPrank(); + vm.startPrank(accountOwner); + usdx.approve(address(zap), amount); + zap.burn(amount, accountId); + vm.stopPrank(); -// assertEq(perpsMarket.debt(accountId), debt - balanceBefore); -// assertEq(usdx.balanceOf(accountOwner), 0); + assertEq(perpsMarket.debt(accountId), debt - balanceBefore); + assertEq(usdx.balanceOf(accountOwner), 0); -// assertEq(weth.balanceOf(address(zap)), 0); -// assertEq(usdc.balanceOf(address(zap)), 0); -// assertEq(usdx.balanceOf(address(zap)), 0); -// } - -// function testBurnLargeDebtWithOI_Partial_NotAccountOwner_Success() -// public -// selectFork(FORK["1_zap"]) -// { -// uint128 accountId = largeAccountIdWithOi; -// address user = vm.addr(1234); + assertEq(weth.balanceOf(address(zap)), 0); + assertEq(usdc.balanceOf(address(zap)), 0); + assertEq(usdx.balanceOf(address(zap)), 0); + } -// // check account debt -// uint256 debt = perpsMarket.debt(accountId); + function testBurnLargeDebtWithOI_Partial_NotAccountOwner_Success() + public + selectFork(FORK["1_zap"]) + { + uint128 accountId = largeAccountIdWithOi; + address user = vm.addr(1234); -// uint256 amount = debt - 1e6; + // check account debt + uint256 debt = perpsMarket.debt(accountId); -// _spin(user, usdx, amount); -// uint256 balanceBefore = usdx.balanceOf(user); + uint256 amount = debt - 1e6; -// vm.startPrank(user); -// usdx.approve(address(zap), amount); -// zap.burn(amount, accountId); -// vm.stopPrank(); + _spin(user, usdx, amount); + uint256 balanceBefore = usdx.balanceOf(user); -// assertEq(perpsMarket.debt(accountId), debt - balanceBefore); -// assertEq(usdx.balanceOf(user), 0); + vm.startPrank(user); + usdx.approve(address(zap), amount); + zap.burn(amount, accountId); + vm.stopPrank(); -// assertEq(weth.balanceOf(address(zap)), 0); -// assertEq(usdc.balanceOf(address(zap)), 0); -// assertEq(usdx.balanceOf(address(zap)), 0); -// } + assertEq(perpsMarket.debt(accountId), debt - balanceBefore); + assertEq(usdx.balanceOf(user), 0); -// // TODO fix plumber tests - -// function testFlush_Plumber_Success() public selectFork(FORK["1_zap"]) { -// uint256 amountWeth = 1234 ether; -// uint256 amountUsdx = 56_789 ether; -// _spin(address(zap), weth, amountWeth); -// _spin(address(zap), usdx, amountUsdx); - -// uint256 zapWethBefore = weth.balanceOf(address(zap)); -// uint256 zapUsdxBefore = usdx.balanceOf(address(zap)); - -// uint256 plumberWethBefore = weth.balanceOf(address(this)); -// uint256 plumberUsdxBefore = usdx.balanceOf(address(this)); - -// // this test contract created the Zap contract and should be the -// owner -// zap.flush(address(usdx)); - -// assertEq(usdx.balanceOf(address(zap)), 0); -// assertEq(weth.balanceOf(address(zap)), zapWethBefore); + assertEq(weth.balanceOf(address(zap)), 0); + assertEq(usdc.balanceOf(address(zap)), 0); + assertEq(usdx.balanceOf(address(zap)), 0); + } -// assertEq( -// usdx.balanceOf(address(this)), plumberUsdxBefore + zapUsdxBefore -// ); -// assertEq(weth.balanceOf(address(this)), plumberWethBefore); - -// zap.flush(address(weth)); - -// assertEq(usdx.balanceOf(address(zap)), 0); -// assertEq(weth.balanceOf(address(zap)), 0); - -// assertEq( -// usdx.balanceOf(address(this)), plumberUsdxBefore + zapUsdxBefore -// ); -// assertEq( -// weth.balanceOf(address(this)), plumberWethBefore + zapWethBefore -// ); -// } - -// error OnlyPlumber(); - -// function testFlush_NotPlumberer_Fail() public selectFork(FORK["1_zap"]) { -// uint256 amountWeth = 1234 ether; -// uint256 amountUsdx = 56_789 ether; -// _spin(address(zap), weth, amountWeth); -// _spin(address(zap), usdx, amountUsdx); - -// uint256 zapWethBefore = weth.balanceOf(address(zap)); -// uint256 zapUsdxBefore = usdx.balanceOf(address(zap)); - -// uint256 plumberWethBefore = weth.balanceOf(address(this)); -// uint256 plumberUsdxBefore = usdx.balanceOf(address(this)); - -// // this test contract created the Zap contract and should be the -// owner -// vm.prank(vm.addr(987_654_321)); -// vm.expectRevert(abi.encodeWithSelector(OnlyPlumber.selector)); -// zap.flush(address(usdx)); - -// assertEq(usdx.balanceOf(address(zap)), zapUsdxBefore); -// assertEq(weth.balanceOf(address(zap)), zapWethBefore); - -// assertEq(usdx.balanceOf(address(this)), plumberUsdxBefore); -// assertEq(weth.balanceOf(address(this)), plumberWethBefore); -// } - -// function testFlushNominate_Plumber_Success() -// public -// selectFork(FORK["1_zap"]) -// { -// address currentPlumber = zap.PLUMBER(); -// address nominated = address(0xdeadbeef); - -// assertGt(uint160(currentPlumber), 0); - -// zap.nominatePlumber(nominated); - -// address nominatedPlumber = zap.nominatedPlumber(); -// assertEq(nominatedPlumber, nominated); -// assertEq(currentPlumber, zap.PLUMBER()); - -// vm.prank(nominated); -// zap.acceptPlumberNomination(); -// address newPlumber = zap.PLUMBER(); -// assertEq(nominated, newPlumber); -// } - -// function testFlushDesignate_NotPlumber_Fail() -// public -// selectFork(FORK["1_zap"]) -// { -// address currentPlumber = zap.PLUMBER(); -// address nominated = address(0); - -// assertGt(uint160(currentPlumber), 0); - -// vm.prank(vm.addr(987_654_321)); -// vm.expectRevert(abi.encodeWithSelector(OnlyPlumber.selector)); -// zap.nominatePlumber(nominated); - -// address newPlumber = zap.PLUMBER(); -// assertEq(newPlumber, currentPlumber); -// assertGt(uint160(newPlumber), 0); -// } - -// function testWithdrawNoOiNoDebt_AllCollateral_AccountOwner_Success() -// public -// selectFork(FORK["1_zap"]) -// { -// address user = vm.addr(5); -// uint32 amount = 1_000_000_000; -// _spin(user, usdx, amount); - -// vm.startPrank(user); -// uint128 accountId = perpsMarket.createAccount(); -// int128 margin = int128(int32(amount)); - -// usdx.approve(address(perpsMarket), amount); -// perpsMarket.modifyCollateral(accountId, 0, margin); - -// assertEq(usdx.balanceOf(user), 0); -// assertEq(perpsMarket.totalCollateralValue(accountId), amount); - -// perpsMarket.grantPermission( -// accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) -// ); -// zap.withdraw({ -// _synthId: 0, -// _amount: amount, -// _accountId: accountId, -// _receiver: user -// }); -// vm.stopPrank(); - -// assertEq(usdx.balanceOf(user), amount); -// assertEq(perpsMarket.totalCollateralValue(accountId), 0); - -// assertEq(usdc.balanceOf(address(zap)), 0); -// assertEq(susdc.balanceOf(address(zap)), 0); -// assertEq(usdx.balanceOf(address(zap)), 0); -// assertFalse( -// perpsMarket.isAuthorized( -// accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) -// ) -// ); -// } - -// function testWithdrawNoOiNoDebt_AllCollateral_NotAccounttOwner_Fail() -// public -// selectFork(FORK["1_zap"]) -// { -// address user = vm.addr(5); -// uint32 amount = 1_000_000_000; -// _spin(user, usdx, amount); - -// vm.startPrank(user); -// uint128 accountId = perpsMarket.createAccount(); -// int128 margin = int128(int32(amount)); - -// usdx.approve(address(perpsMarket), amount); -// perpsMarket.modifyCollateral(accountId, 0, margin); - -// assertEq(usdx.balanceOf(user), 0); - -// perpsMarket.grantPermission( -// accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) -// ); -// vm.stopPrank(); - -// vm.expectRevert(abi.encodeWithSelector(NotPermitted.selector)); -// zap.withdraw({ -// _synthId: 0, -// _amount: amount, -// _accountId: accountId, -// _receiver: user -// }); - -// assertEq(usdx.balanceOf(user), 0); -// assertEq(perpsMarket.totalCollateralValue(accountId), amount); - -// assertEq(usdc.balanceOf(address(zap)), 0); -// assertEq(susdc.balanceOf(address(zap)), 0); -// assertEq(usdx.balanceOf(address(zap)), 0); -// assertTrue( -// perpsMarket.isAuthorized( -// accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) -// ) -// ); -// } - -// function testWithdrawNoOiNoDebt_AccountOwner_ZapNotPermitted_Fail() -// public -// selectFork(FORK["1_zap"]) -// { -// address user = vm.addr(5); -// uint32 amount = 1_000_000_000; -// _spin(user, usdx, amount); - -// vm.startPrank(user); -// uint128 accountId = perpsMarket.createAccount(); -// int128 margin = int128(int32(amount)); - -// usdx.approve(address(perpsMarket), amount); -// perpsMarket.modifyCollateral(accountId, 0, margin); - -// assertEq(usdx.balanceOf(user), 0); -// assertEq(perpsMarket.totalCollateralValue(accountId), amount); - -// vm.expectRevert( -// abi.encodeWithSelector( -// IPerpsMarket.PermissionDenied.selector, -// accountId, -// _PERPS_MODIFY_COLLATERAL_PERMISSION, -// address(zap) -// ) -// ); -// zap.withdraw({ -// _synthId: 0, -// _amount: amount, -// _accountId: accountId, -// _receiver: user -// }); - -// vm.stopPrank(); - -// assertEq(usdx.balanceOf(user), 0); -// assertEq(perpsMarket.totalCollateralValue(accountId), amount); - -// assertEq(usdc.balanceOf(address(zap)), 0); -// assertEq(susdc.balanceOf(address(zap)), 0); -// assertEq(usdx.balanceOf(address(zap)), 0); -// assertFalse( -// perpsMarket.isAuthorized( -// accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) -// ) -// ); -// } - -// // Basic functional tests, these are similar to existing tests and were -// used -// // to ensure this harness worked correctly -// function testBuySuccess(uint128 amount) public selectFork(FORK["1_zap"]) -// { -// // D18, fuzzing up to 3e38 -// vm.assume(amount < uint128(type(int128).max / 9)); -// vm.assume(amount > 10); - -// address user = vm.addr(1); -// // uint256 amount = 1000e6; - -// _spin(user, usdx, amount); - -// assertEq(usdx.balanceOf(user), amount); -// assertEq(susdc.balanceOf(user), 0); - -// vm.startPrank(user); -// usdx.approve(address(zap), amount); - -// (uint256 received, address synth) = zap.buy({ -// _synthId: zap.SSTATA_SPOT_ID(), -// _amount: amount, -// _minAmountOut: 0, -// _receiver: user -// }); -// vm.stopPrank(); - -// assertEq(synth, address(susdc)); -// assertGe(received, amount * 9 / 10); -// assertEq(usdx.balanceOf(user), 0); -// assertGe(susdc.balanceOf(user), amount * 9 / 10); - -// assertEq(usdc.balanceOf(address(zap)), 0); -// assertEq(susdc.balanceOf(address(zap)), 0); -// assertEq(usdx.balanceOf(address(zap)), 0); -// } - -// function testSellSuccess( /*uint128 amount*/ ) -// public -// selectFork(FORK["1_zap"]) -// { -// address user = vm.addr(2); -// // _maxCoreCapacity(); -// // vm.assume(amount < 1e20); -// uint256 amount = 1000e18; -// uint256 minAmountOut = amount * 99 / 100; -// _spin(user, usdx, amount); - -// vm.startPrank(user); -// usdx.approve(address(zap), amount); - -// (uint256 received,) = zap.buy({ -// _synthId: zap.SSTATA_SPOT_ID(), -// _amount: amount, -// _minAmountOut: minAmountOut, -// _receiver: user -// }); - -// assertEq(usdx.balanceOf(user), 0); -// assertEq(usdc.balanceOf(user), 0); -// assertEq(susdc.balanceOf(user), received); -// assertGe(received, minAmountOut); -// assertGe(susdc.balanceOf(user), minAmountOut); - -// susdc.approve(address(zap), received); -// minAmountOut = received * 99 / 100; - -// received = zap.sell({ -// _synthId: zap.SSTATA_SPOT_ID(), -// _amount: received, -// _minAmountOut: minAmountOut, -// _receiver: user -// }); -// vm.stopPrank(); - -// assertGe(usdx.balanceOf(user), minAmountOut); -// assertGe(received, minAmountOut); -// assertEq(usdx.balanceOf(user), received); -// assertEq(susdc.balanceOf(user), 0); - -// assertEq(usdc.balanceOf(address(zap)), 0); -// assertEq(susdc.balanceOf(address(zap)), 0); -// assertEq(usdx.balanceOf(address(zap)), 0); -// } - -// function testUnwrap( /* uint32 amount */ ) -// public -// selectFork(FORK["1_zap"]) -// { -// address user = vm.addr(4); -// uint256 amount = 1000e6; -// _spin(user, usdc, amount); - -// vm.startPrank(user); -// usdc.approve(address(zap), amount); - -// uint256 wrapped = zap.wrap({ -// _token: address(usdc), -// _synthId: zap.SSTATA_SPOT_ID(), -// _amount: amount, -// _minAmountOut: amount, -// _receiver: user -// }); - -// assertEq(usdc.balanceOf(user), 0); -// assertEq(wrapped, amount * 1e12); -// assertEq(susdc.balanceOf(user), amount * 1e12); - -// susdc.approve(address(zap), type(uint256).max); - -// uint256 unwrapped = zap.unwrap({ -// _token: address(usdc), -// _synthId: zap.SSTATA_SPOT_ID(), -// _amount: wrapped, -// _minAmountOut: amount, -// _receiver: user -// }); -// vm.stopPrank(); - -// assertEq(unwrapped, amount); -// assertEq(usdc.balanceOf(user), amount); -// assertEq(susdc.balanceOf(user), 0); - -// assertEq(usdc.balanceOf(address(zap)), 0); -// assertEq(susdc.balanceOf(address(zap)), 0); -// assertEq(usdx.balanceOf(address(zap)), 0); -// } - -// function testWrap( /*uint64 amount*/ ) public selectFork(FORK["1_zap"]) { -// address user = vm.addr(6); -// uint64 amount = 1000e6; -// _spin(user, usdc, amount); - -// assertEq(usdc.balanceOf(user), amount); -// assertEq(susdc.balanceOf(user), 0); - -// vm.startPrank(user); -// usdc.approve(address(zap), amount); - -// uint256 wrapped = zap.wrap({ -// _token: address(usdc), -// _synthId: zap.SSTATA_SPOT_ID(), -// _amount: amount, -// _minAmountOut: amount, -// _receiver: user -// }); -// vm.stopPrank(); - -// assertEq(wrapped, uint256(amount) * 1e12); -// assertEq(usdc.balanceOf(user), 0); -// assertEq(susdc.balanceOf(user), wrapped); - -// assertEq(usdc.balanceOf(address(zap)), 0); -// assertEq(susdc.balanceOf(address(zap)), 0); -// assertEq(usdx.balanceOf(address(zap)), 0); -// } - -// function testZapInSuccess( /*uint64 amount*/ ) -// public -// selectFork(FORK["1_zap"]) -// { -// address user = vm.addr(7); -// uint64 amount = 1000e6; -// _spin(user, usdc, amount); - -// assertEq(usdc.balanceOf(user), amount); -// assertEq(usdx.balanceOf(user), 0); - -// vm.startPrank(user); -// usdc.approve(address(zap), amount); - -// uint256 zapped = -// zap.zapIn({_amount: amount, _minAmountOut: amount, _receiver: -// user}); -// vm.stopPrank(); - -// assertGe(zapped, uint256(amount) * 99e10); // amount * 1e12 * 0.99 -// assertEq(usdc.balanceOf(user), 0); -// assertEq(usdx.balanceOf(user), zapped); - -// assertEq(usdc.balanceOf(address(zap)), 0); -// assertEq(susdc.balanceOf(address(zap)), 0); -// assertEq(usdx.balanceOf(address(zap)), 0); -// } - -// function testZapOutSuccess( /*uint64 amount*/ ) -// public -// selectFork(FORK["1_zap"]) -// { -// address user = vm.addr(8); -// // vm.assume(amount > 1e12); -// uint256 amount = 250e18; -// _spin(address(this), usdc, amount / 1e12); -// usdc.approve(address(zap), amount / 1e12); -// zap.wrap({ -// _token: address(usdc), -// _synthId: zap.SSTATA_SPOT_ID(), -// _amount: amount / 1e12, -// _minAmountOut: amount / 1e12, -// _receiver: address(this) -// }); -// assertEq(usdc.balanceOf(address(this)), 0); -// assertEq(susdc.balanceOf(address(this)), amount); - -// _spin(user, usdx, amount); - -// assertEq(usdc.balanceOf(user), 0); -// assertEq(usdx.balanceOf(user), amount); - -// vm.startPrank(user); -// usdx.approve(address(zap), amount); - -// uint256 zapped = zap.zapOut({ -// _amount: amount, -// _minAmountOut: amount * 9 / 1e13, -// _receiver: user -// }); -// vm.stopPrank(); - -// assertGe(zapped * 1e12, amount * 9 / 10); -// assertEq(usdc.balanceOf(user), zapped); -// assertEq(usdx.balanceOf(user), 0); - -// assertEq(usdc.balanceOf(address(zap)), 0); -// assertEq(susdc.balanceOf(address(zap)), 0); -// assertEq(usdx.balanceOf(address(zap)), 0); -// } - -// } + // TODO fix plumber tests + + function testFlush_Plumber_Success() public selectFork(FORK["1_zap"]) { + uint256 amountWeth = 1234 ether; + uint256 amountUsdx = 56_789 ether; + _spin(address(zap), weth, amountWeth); + _spin(address(zap), usdx, amountUsdx); + + uint256 zapWethBefore = weth.balanceOf(address(zap)); + uint256 zapUsdxBefore = usdx.balanceOf(address(zap)); + + uint256 plumberWethBefore = weth.balanceOf(address(this)); + uint256 plumberUsdxBefore = usdx.balanceOf(address(this)); + + // this test contract created the Zap contract and should be the owner + zap.flush(address(usdx)); + + assertEq(usdx.balanceOf(address(zap)), 0); + assertEq(weth.balanceOf(address(zap)), zapWethBefore); + + assertEq( + usdx.balanceOf(address(this)), plumberUsdxBefore + zapUsdxBefore + ); + assertEq(weth.balanceOf(address(this)), plumberWethBefore); + + zap.flush(address(weth)); + + assertEq(usdx.balanceOf(address(zap)), 0); + assertEq(weth.balanceOf(address(zap)), 0); + + assertEq( + usdx.balanceOf(address(this)), plumberUsdxBefore + zapUsdxBefore + ); + assertEq( + weth.balanceOf(address(this)), plumberWethBefore + zapWethBefore + ); + } + + error OnlyPlumber(); + + function testFlush_NotPlumberer_Fail() public selectFork(FORK["1_zap"]) { + uint256 amountWeth = 1234 ether; + uint256 amountUsdx = 56_789 ether; + _spin(address(zap), weth, amountWeth); + _spin(address(zap), usdx, amountUsdx); + + uint256 zapWethBefore = weth.balanceOf(address(zap)); + uint256 zapUsdxBefore = usdx.balanceOf(address(zap)); + + uint256 plumberWethBefore = weth.balanceOf(address(this)); + uint256 plumberUsdxBefore = usdx.balanceOf(address(this)); + + // this test contract created the Zap contract and should be the owner + vm.prank(vm.addr(987_654_321)); + vm.expectRevert(abi.encodeWithSelector(OnlyPlumber.selector)); + zap.flush(address(usdx)); + + assertEq(usdx.balanceOf(address(zap)), zapUsdxBefore); + assertEq(weth.balanceOf(address(zap)), zapWethBefore); + + assertEq(usdx.balanceOf(address(this)), plumberUsdxBefore); + assertEq(weth.balanceOf(address(this)), plumberWethBefore); + } + + function testFlushNominate_Plumber_Success() + public + selectFork(FORK["1_zap"]) + { + address currentPlumber = zap.PLUMBER(); + address nominated = address(0xdeadbeef); + + assertGt(uint160(currentPlumber), 0); + + zap.nominatePlumber(nominated); + + address nominatedPlumber = zap.nominatedPlumber(); + assertEq(nominatedPlumber, nominated); + assertEq(currentPlumber, zap.PLUMBER()); + + vm.prank(nominated); + zap.acceptPlumberNomination(); + address newPlumber = zap.PLUMBER(); + assertEq(nominated, newPlumber); + } + + function testFlushDesignate_NotPlumber_Fail() + public + selectFork(FORK["1_zap"]) + { + address currentPlumber = zap.PLUMBER(); + address nominated = address(0); + + assertGt(uint160(currentPlumber), 0); + + vm.prank(vm.addr(987_654_321)); + vm.expectRevert(abi.encodeWithSelector(OnlyPlumber.selector)); + zap.nominatePlumber(nominated); + + address newPlumber = zap.PLUMBER(); + assertEq(newPlumber, currentPlumber); + assertGt(uint160(newPlumber), 0); + } + + function testWithdrawNoOiNoDebt_AllCollateral_AccountOwner_Success() + public + selectFork(FORK["1_zap"]) + { + address user = vm.addr(5); + uint32 amount = 1_000_000_000; + _spin(user, usdx, amount); + + vm.startPrank(user); + uint128 accountId = perpsMarket.createAccount(); + int128 margin = int128(int32(amount)); + + usdx.approve(address(perpsMarket), amount); + perpsMarket.modifyCollateral(accountId, 0, margin); + + assertEq(usdx.balanceOf(user), 0); + assertEq(perpsMarket.totalCollateralValue(accountId), amount); + + perpsMarket.grantPermission( + accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) + ); + zap.withdraw({ + _synthId: 0, + _amount: amount, + _accountId: accountId, + _receiver: user + }); + vm.stopPrank(); + + assertEq(usdx.balanceOf(user), amount); + assertEq(perpsMarket.totalCollateralValue(accountId), 0); + + assertEq(usdc.balanceOf(address(zap)), 0); + assertEq(susdc.balanceOf(address(zap)), 0); + assertEq(usdx.balanceOf(address(zap)), 0); + assertFalse( + perpsMarket.isAuthorized( + accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) + ) + ); + } + + function testWithdrawNoOiNoDebt_AllCollateral_NotAccounttOwner_Fail() + public + selectFork(FORK["1_zap"]) + { + address user = vm.addr(5); + uint32 amount = 1_000_000_000; + _spin(user, usdx, amount); + + vm.startPrank(user); + uint128 accountId = perpsMarket.createAccount(); + int128 margin = int128(int32(amount)); + + usdx.approve(address(perpsMarket), amount); + perpsMarket.modifyCollateral(accountId, 0, margin); + + assertEq(usdx.balanceOf(user), 0); + + perpsMarket.grantPermission( + accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) + ); + vm.stopPrank(); + + vm.expectRevert(abi.encodeWithSelector(NotPermitted.selector)); + zap.withdraw({ + _synthId: 0, + _amount: amount, + _accountId: accountId, + _receiver: user + }); + + assertEq(usdx.balanceOf(user), 0); + assertEq(perpsMarket.totalCollateralValue(accountId), amount); + + assertEq(usdc.balanceOf(address(zap)), 0); + assertEq(susdc.balanceOf(address(zap)), 0); + assertEq(usdx.balanceOf(address(zap)), 0); + assertTrue( + perpsMarket.isAuthorized( + accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) + ) + ); + } + + function testWithdrawNoOiNoDebt_AccountOwner_ZapNotPermitted_Fail() + public + selectFork(FORK["1_zap"]) + { + address user = vm.addr(5); + uint32 amount = 1_000_000_000; + _spin(user, usdx, amount); + + vm.startPrank(user); + uint128 accountId = perpsMarket.createAccount(); + int128 margin = int128(int32(amount)); + + usdx.approve(address(perpsMarket), amount); + perpsMarket.modifyCollateral(accountId, 0, margin); + + assertEq(usdx.balanceOf(user), 0); + assertEq(perpsMarket.totalCollateralValue(accountId), amount); + + vm.expectRevert( + abi.encodeWithSelector( + IPerpsMarket.PermissionDenied.selector, + accountId, + _PERPS_MODIFY_COLLATERAL_PERMISSION, + address(zap) + ) + ); + zap.withdraw({ + _synthId: 0, + _amount: amount, + _accountId: accountId, + _receiver: user + }); + + vm.stopPrank(); + + assertEq(usdx.balanceOf(user), 0); + assertEq(perpsMarket.totalCollateralValue(accountId), amount); + + assertEq(usdc.balanceOf(address(zap)), 0); + assertEq(susdc.balanceOf(address(zap)), 0); + assertEq(usdx.balanceOf(address(zap)), 0); + assertFalse( + perpsMarket.isAuthorized( + accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) + ) + ); + } + + // Basic functional tests, these are similar to existing tests and were used + // to ensure this harness worked correctly + function testBuySuccess(uint128 amount) public selectFork(FORK["1_zap"]) { + // D18, fuzzing up to 3e38 + vm.assume(amount < uint128(type(int128).max / 9)); + vm.assume(amount > 10); + + address user = vm.addr(1); + // uint256 amount = 1000e6; + + _spin(user, usdx, amount); + + assertEq(usdx.balanceOf(user), amount); + assertEq(susdc.balanceOf(user), 0); + + vm.startPrank(user); + usdx.approve(address(zap), amount); + + (uint256 received, address synth) = zap.buy({ + _synthId: zap.SSTATA_SPOT_ID(), + _amount: amount, + _minAmountOut: 0, + _receiver: user + }); + vm.stopPrank(); + + assertEq(synth, address(susdc)); + assertGe(received, amount * 9 / 10); + assertEq(usdx.balanceOf(user), 0); + assertGe(susdc.balanceOf(user), amount * 9 / 10); + + assertEq(usdc.balanceOf(address(zap)), 0); + assertEq(susdc.balanceOf(address(zap)), 0); + assertEq(usdx.balanceOf(address(zap)), 0); + } + + function testSellSuccess( /*uint128 amount*/ ) + public + selectFork(FORK["1_zap"]) + { + address user = vm.addr(2); + // _maxCoreCapacity(); + // vm.assume(amount < 1e20); + uint256 amount = 1000e18; + uint256 minAmountOut = amount * 99 / 100; + _spin(user, usdx, amount); + + vm.startPrank(user); + usdx.approve(address(zap), amount); + + (uint256 received,) = zap.buy({ + _synthId: zap.SSTATA_SPOT_ID(), + _amount: amount, + _minAmountOut: minAmountOut, + _receiver: user + }); + + assertEq(usdx.balanceOf(user), 0); + assertEq(usdc.balanceOf(user), 0); + assertEq(susdc.balanceOf(user), received); + assertGe(received, minAmountOut); + assertGe(susdc.balanceOf(user), minAmountOut); + + susdc.approve(address(zap), received); + minAmountOut = received * 99 / 100; + + received = zap.sell({ + _synthId: zap.SSTATA_SPOT_ID(), + _amount: received, + _minAmountOut: minAmountOut, + _receiver: user + }); + vm.stopPrank(); + + assertGe(usdx.balanceOf(user), minAmountOut); + assertGe(received, minAmountOut); + assertEq(usdx.balanceOf(user), received); + assertEq(susdc.balanceOf(user), 0); + + assertEq(usdc.balanceOf(address(zap)), 0); + assertEq(susdc.balanceOf(address(zap)), 0); + assertEq(usdx.balanceOf(address(zap)), 0); + } + + function testUnwrap( /* uint32 amount */ ) + public + selectFork(FORK["1_zap"]) + { + address user = vm.addr(4); + uint256 amount = 1000e6; + _spin(user, usdc, amount); + + vm.startPrank(user); + usdc.approve(address(zap), amount); + + uint256 wrapped = zap.wrap({ + _token: address(usdc), + _synthId: zap.SSTATA_SPOT_ID(), + _amount: amount, + _minAmountOut: amount, + _receiver: user + }); + + assertEq(usdc.balanceOf(user), 0); + assertEq(wrapped, amount * 1e12); + assertEq(susdc.balanceOf(user), amount * 1e12); + + susdc.approve(address(zap), type(uint256).max); + + uint256 unwrapped = zap.unwrap({ + _token: address(usdc), + _synthId: zap.SSTATA_SPOT_ID(), + _amount: wrapped, + _minAmountOut: amount, + _receiver: user + }); + vm.stopPrank(); + + assertEq(unwrapped, amount); + assertEq(usdc.balanceOf(user), amount); + assertEq(susdc.balanceOf(user), 0); + + assertEq(usdc.balanceOf(address(zap)), 0); + assertEq(susdc.balanceOf(address(zap)), 0); + assertEq(usdx.balanceOf(address(zap)), 0); + } + + function testWrap( /*uint64 amount*/ ) public selectFork(FORK["1_zap"]) { + address user = vm.addr(6); + uint64 amount = 1000e6; + _spin(user, usdc, amount); + + assertEq(usdc.balanceOf(user), amount); + assertEq(susdc.balanceOf(user), 0); + + vm.startPrank(user); + usdc.approve(address(zap), amount); + + uint256 wrapped = zap.wrap({ + _token: address(usdc), + _synthId: zap.SSTATA_SPOT_ID(), + _amount: amount, + _minAmountOut: amount, + _receiver: user + }); + vm.stopPrank(); + + assertEq(wrapped, uint256(amount) * 1e12); + assertEq(usdc.balanceOf(user), 0); + assertEq(susdc.balanceOf(user), wrapped); + + assertEq(usdc.balanceOf(address(zap)), 0); + assertEq(susdc.balanceOf(address(zap)), 0); + assertEq(usdx.balanceOf(address(zap)), 0); + } + + function testZapInSuccess( /*uint64 amount*/ ) + public + selectFork(FORK["1_zap"]) + { + address user = vm.addr(7); + uint64 amount = 1000e6; + _spin(user, usdc, amount); + + assertEq(usdc.balanceOf(user), amount); + assertEq(usdx.balanceOf(user), 0); + + vm.startPrank(user); + usdc.approve(address(zap), amount); + + uint256 zapped = + zap.zapIn({_amount: amount, _minAmountOut: amount, _receiver: user}); + vm.stopPrank(); + + assertGe(zapped, uint256(amount) * 99e10); // amount * 1e12 * 0.99 + assertEq(usdc.balanceOf(user), 0); + assertEq(usdx.balanceOf(user), zapped); + + assertEq(usdc.balanceOf(address(zap)), 0); + assertEq(susdc.balanceOf(address(zap)), 0); + assertEq(usdx.balanceOf(address(zap)), 0); + } + + function testZapOutSuccess( /*uint64 amount*/ ) + public + selectFork(FORK["1_zap"]) + { + address user = vm.addr(8); + // vm.assume(amount > 1e12); + uint256 amount = 250e18; + _spin(address(this), usdc, amount / 1e12); + usdc.approve(address(zap), amount / 1e12); + zap.wrap({ + _token: address(usdc), + _synthId: zap.SSTATA_SPOT_ID(), + _amount: amount / 1e12, + _minAmountOut: amount / 1e12, + _receiver: address(this) + }); + assertEq(usdc.balanceOf(address(this)), 0); + assertEq(susdc.balanceOf(address(this)), amount); + + _spin(user, usdx, amount); + + assertEq(usdc.balanceOf(user), 0); + assertEq(usdx.balanceOf(user), amount); + + vm.startPrank(user); + usdx.approve(address(zap), amount); + + uint256 zapped = zap.zapOut({ + _amount: amount, + _minAmountOut: amount * 9 / 1e13, + _receiver: user + }); + vm.stopPrank(); + + assertGe(zapped * 1e12, amount * 9 / 10); + assertEq(usdc.balanceOf(user), zapped); + assertEq(usdx.balanceOf(user), 0); + + assertEq(usdc.balanceOf(address(zap)), 0); + assertEq(susdc.balanceOf(address(zap)), 0); + assertEq(usdx.balanceOf(address(zap)), 0); + } + +} diff --git a/test/Unwind.t.sol b/test/Unwind.t.sol index ed0d432..8c36d6e 100644 --- a/test/Unwind.t.sol +++ b/test/Unwind.t.sol @@ -35,11 +35,11 @@ contract UnwindTest is Bootstrap, Errors { bytes swapPath; string pathId; - // function test_unwind_is_authorized() public base { - // vm.prank(ACTOR); - // vm.expectRevert(NotPermitted.selector); - // zap.unwind(0, 0, 0, address(0), "", /*todo*/ 0, 0, 0, address(0)); - // } + function test_unwind_is_authorized() public base { + vm.prank(ACTOR); + vm.expectRevert(NotPermitted.selector); + zap.unwind(0, 0, 0, address(0), "", /*todo*/ 0, 0, 0, address(0)); + } // /// @custom:todo // function test_unwind_base() public base { From ea1ca6481169dd4f2b4ef848405841be5084f06e Mon Sep 17 00:00:00 2001 From: Moss Date: Fri, 7 Mar 2025 14:40:02 +0100 Subject: [PATCH 19/24] doc --- docs/book.toml | 1 + docs/src/README.md | 6 +- docs/src/SUMMARY.md | 1 + docs/src/src/Zap.sol/contract.Zap.md | 185 ++++++++++++++++-- .../interfaces/IAave.sol/interface.IPool.md | 2 +- .../interfaces/IERC20.sol/interface.IERC20.md | 2 +- .../IERC4626.sol/interface.IERC4626.md | 37 ++++ .../ISynthetix.sol/interface.IPerpsMarket.md | 17 +- .../ISynthetix.sol/interface.ISpotMarket.md | 2 +- .../IUniswap.sol/interface.IQuoter.md | 2 +- .../IUniswap.sol/interface.IRouter.md | 2 +- docs/src/src/interfaces/README.md | 1 + .../src/utils/Errors.sol/contract.Errors.md | 2 +- .../src/src/utils/Flush.sol/contract.Flush.md | 53 ++++- .../Reentrancy.sol/contract.Reentrancy.md | 2 +- .../library.SafeERC20.md | 2 +- 16 files changed, 285 insertions(+), 32 deletions(-) create mode 100644 docs/src/src/interfaces/IERC4626.sol/interface.IERC4626.md diff --git a/docs/book.toml b/docs/book.toml index 00b424c..8455aed 100644 --- a/docs/book.toml +++ b/docs/book.toml @@ -6,6 +6,7 @@ title = "" no-section-label = true additional-js = ["solidity.min.js"] additional-css = ["book.css"] +mathjax-support = true git-repository-url = "https://github.com/moss-eth/zap" [output.html.fold] diff --git a/docs/src/README.md b/docs/src/README.md index 278e995..d6e5b6d 100644 --- a/docs/src/README.md +++ b/docs/src/README.md @@ -72,7 +72,7 @@ USDC <--(spot market)--> sUSDC <--(spot market)--> USDx ## How to Deploy -- See the `deployments/` folder for Arbitrum and Base deployments. +- See the `deployments/` folder for Base deployments. How to Deploy: @@ -82,10 +82,6 @@ How to Deploy: ``` make deploy_base ``` -3. Deploy to Arbitrum - ``` - make deploy_arbitrum - ``` ## Audits diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index 5ae87ee..2001e86 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -4,6 +4,7 @@ - [❱ interfaces](src/interfaces/README.md) - [IPool](src/interfaces/IAave.sol/interface.IPool.md) - [IERC20](src/interfaces/IERC20.sol/interface.IERC20.md) + - [IERC4626](src/interfaces/IERC4626.sol/interface.IERC4626.md) - [ISpotMarket](src/interfaces/ISynthetix.sol/interface.ISpotMarket.md) - [IPerpsMarket](src/interfaces/ISynthetix.sol/interface.IPerpsMarket.md) - [IRouter](src/interfaces/IUniswap.sol/interface.IRouter.md) diff --git a/docs/src/src/Zap.sol/contract.Zap.md b/docs/src/src/Zap.sol/contract.Zap.md index 6672cc5..f23855e 100644 --- a/docs/src/src/Zap.sol/contract.Zap.md +++ b/docs/src/src/Zap.sol/contract.Zap.md @@ -1,19 +1,29 @@ # Zap -[Git Source](https://github.com/moss-eth/zap/blob/59cf0756a77f382e301eda36c7e1793c595fd9b7/src/Zap.sol) +[Git Source](https://github.com/moss-eth/zap/blob/7ecc5cc79642d99fe6248a4895ed17a8ea025990/src/Zap.sol) **Inherits:** [Reentrancy](/src/utils/Reentrancy.sol/contract.Reentrancy.md), [Errors](/src/utils/Errors.sol/contract.Errors.md), [Flush](/src/utils/Flush.sol/contract.Flush.md) **Authors:** -@jaredborders, @flocqst, @barrasso, @moss-eth +@jaredborders, @flocqst, @barrasso, @moss-eth, @cmontecoding *idle token balances are not safe* *intended for standalone use; do not inherit* +**Notes:** +- synthetix: zap USDC into and out of USDx + +- aave: flash loan USDC to unwind synthetix collateral + +- odos: swap unwound collateral for USDC to repay flashloan + ## State Variables ### USDC +**Note:** +circle: + ```solidity address public immutable USDC; @@ -21,6 +31,9 @@ address public immutable USDC; ### MODIFY_PERMISSION +**Note:** +synthetix: + ```solidity bytes32 public constant MODIFY_PERMISSION = "PERPS_MODIFY_COLLATERAL"; @@ -76,7 +89,24 @@ uint128 public immutable SUSDC_SPOT_ID; ``` +### SSTATA_SPOT_ID + +```solidity +uint128 public immutable SSTATA_SPOT_ID; +``` + + +### SSTATA + +```solidity +address public immutable SSTATA; +``` + + ### REFERRAL_CODE +**Note:** +aave: + ```solidity uint16 public constant REFERRAL_CODE = 0; @@ -90,7 +120,17 @@ address public immutable AAVE; ``` +### STATA + +```solidity +address public immutable STATA; +``` + + ### ROUTER +**Note:** +odos: + ```solidity address public immutable ROUTER; @@ -105,11 +145,14 @@ address public immutable ROUTER; constructor( address _usdc, address _usdx, + address _sstata, address _spotMarket, address _perpsMarket, address _referrer, uint128 _susdcSpotId, + uint128 _sstataSpotId, address _aave, + address _stata, address _router ); ``` @@ -118,6 +161,15 @@ constructor( validate caller is authorized to modify synthetix perp position +**Notes:** +- circle: + +- synthetix: + +- aave: + +- odos: + ```solidity modifier isAuthorized(uint128 _accountId); @@ -140,7 +192,7 @@ modifier onlyAave(); ### zapIn -zap USDC into USDx +zap USDC into STATA *caller must grant USDC allowance to this contract* @@ -160,20 +212,20 @@ function zapIn( |----|----|-----------| |`_amount`|`uint256`|amount of USDC to zap| |`_minAmountOut`|`uint256`|acceptable slippage for wrapping and selling| -|`_receiver`|`address`|address to receive USDx| +|`_receiver`|`address`|address to receive STATA| **Returns** |Name|Type|Description| |----|----|-----------| -|`zapped`|`uint256`|amount of USDx received| +|`zapped`|`uint256`|amount of STATA received| ### _zapIn *allowance is assumed* -*following execution, this contract will hold the zapped USDx* +*following execution, this contract will hold the zapped STATA* ```solidity @@ -185,6 +237,22 @@ function _zapIn( returns (uint256 zapped); ``` +### _zapInUSDx + +*allowance is assumed* + +*following execution, this contract will hold the zapped USDx* + + +```solidity +function _zapInUSDx( + uint256 _amount, + uint256 _minAmountOut +) + internal + returns (uint256 zapped); +``` + ### zapOut zap USDx into USDC @@ -232,12 +300,86 @@ function _zapOut( returns (uint256 zapped); ``` +### _zapOutUSDx + +*allowance is assumed* + +*following execution, this contract will hold the zapped USDC* + + +```solidity +function _zapOutUSDx( + uint256 _amount, + uint256 _minAmountOut +) + internal + returns (uint256 zapped); +``` + +### _depositStata + +deposit STATA + + +```solidity +function _depositStata( + uint256 _amount, + address _receiver +) + internal + returns (uint256 shares); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_amount`|`uint256`|amount of STATA to deposit| +|`_receiver`|`address`|address to receive deposited STATA| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|`shares`|`uint256`|received| + + +### _redeemStata + +redeem STATA + + +```solidity +function _redeemStata( + uint256 _shares, + address _receiver +) + internal + returns (uint256 assets); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_shares`|`uint256`|amount of STATA to redeem| +|`_receiver`|`address`|address to receive redeemed STATA| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|`assets`|`uint256`|received| + + ### wrap wrap collateral via synthetix spot market *caller must grant token allowance to this contract* +**Note:** +synth: -> synthetix token representation of an asset with an +acceptable onchain price oracle + ```solidity function wrap( @@ -291,6 +433,10 @@ unwrap collateral via synthetix spot market *caller must grant synth allowance to this contract* +**Note:** +synth: -> synthetix token representation of an asset with an +acceptable onchain price oracle + ```solidity function unwrap( @@ -442,7 +588,8 @@ function _sell( unwind synthetix perp position collateral -*caller must grant USDC allowance to this contract* +**Note:** +synthetix: RBAC permission required: "PERPS_MODIFY_COLLATERAL" ```solidity @@ -466,13 +613,13 @@ function unwind( |Name|Type|Description| |----|----|-----------| |`_accountId`|`uint128`|synthetix perp market account id| -|`_collateralId`|`uint128`|synthetix market id of collateral| +|`_collateralId`|`uint128`|synthetix spot market id or synth id| |`_collateralAmount`|`uint256`|amount of collateral to unwind| |`_collateral`|`address`|address of collateral to unwind| |`_path`|`bytes`|odos path from the sor/assemble api endpoint| |`_zapMinAmountOut`|`uint256`|acceptable slippage for zapping| |`_unwrapMinAmountOut`|`uint256`|acceptable slippage for unwrapping| -|`_swapAmountIn`|`uint256`|acceptable slippage for swapping| +|`_swapAmountIn`|`uint256`|amount intended to be swapped by odos| |`_receiver`|`address`|address to receive unwound collateral| @@ -482,6 +629,9 @@ flashloan callback function *caller must be the Aave lending pool* +**Note:** +caution: calling this function directly is not recommended + ```solidity function executeOperation( @@ -594,6 +744,13 @@ precision loss* *excess USDx will be returned to the caller* +**Notes:** +- synthetix: debt is denominated in USDx + +- aave: debt is denominated in USDC + +- caution: ALL USDx remaining post-burn will be sent to the caller + ```solidity function burn( @@ -632,6 +789,9 @@ function _burn(uint256 _amount, uint128 _accountId) internal; withdraw collateral from synthetix perp position +**Note:** +synthetix: RBAC permission required: "PERPS_MODIFY_COLLATERAL" + ```solidity function withdraw( @@ -658,6 +818,9 @@ function withdraw( *following execution, this contract will hold the withdrawn collateral* +**Note:** +synthetix: RBAC permission required: "PERPS_MODIFY_COLLATERAL" + ```solidity function _withdraw( @@ -670,10 +833,10 @@ function _withdraw( ### swapFrom -swap an amount of tokens for the optimal amount of USDC +swap the input amount of tokens for USDC using Odos *_path USDC is not enforced as the output token during the swap, but -is the expected in the call to push* +is expected in the call to push* *caller must grant token allowance to this contract* diff --git a/docs/src/src/interfaces/IAave.sol/interface.IPool.md b/docs/src/src/interfaces/IAave.sol/interface.IPool.md index 7aa3f02..f12d928 100644 --- a/docs/src/src/interfaces/IAave.sol/interface.IPool.md +++ b/docs/src/src/interfaces/IAave.sol/interface.IPool.md @@ -1,5 +1,5 @@ # IPool -[Git Source](https://github.com/moss-eth/zap/blob/59cf0756a77f382e301eda36c7e1793c595fd9b7/src/interfaces/IAave.sol) +[Git Source](https://github.com/moss-eth/zap/blob/7ecc5cc79642d99fe6248a4895ed17a8ea025990/src/interfaces/IAave.sol) ## Functions diff --git a/docs/src/src/interfaces/IERC20.sol/interface.IERC20.md b/docs/src/src/interfaces/IERC20.sol/interface.IERC20.md index cce5ab6..ff6ea9d 100644 --- a/docs/src/src/interfaces/IERC20.sol/interface.IERC20.md +++ b/docs/src/src/interfaces/IERC20.sol/interface.IERC20.md @@ -1,5 +1,5 @@ # IERC20 -[Git Source](https://github.com/moss-eth/zap/blob/59cf0756a77f382e301eda36c7e1793c595fd9b7/src/interfaces/IERC20.sol) +[Git Source](https://github.com/moss-eth/zap/blob/7ecc5cc79642d99fe6248a4895ed17a8ea025990/src/interfaces/IERC20.sol) ## Functions diff --git a/docs/src/src/interfaces/IERC4626.sol/interface.IERC4626.md b/docs/src/src/interfaces/IERC4626.sol/interface.IERC4626.md new file mode 100644 index 0000000..e79059e --- /dev/null +++ b/docs/src/src/interfaces/IERC4626.sol/interface.IERC4626.md @@ -0,0 +1,37 @@ +# IERC4626 +[Git Source](https://github.com/moss-eth/zap/blob/7ecc5cc79642d99fe6248a4895ed17a8ea025990/src/interfaces/IERC4626.sol) + + +## Functions +### approve + + +```solidity +function approve(address spender, uint256 amount) external returns (bool); +``` + +### deposit + + +```solidity +function deposit( + uint256 assets, + address receiver +) + external + returns (uint256 shares); +``` + +### redeem + + +```solidity +function redeem( + uint256 shares, + address receiver, + address owner +) + external + returns (uint256 assets); +``` + diff --git a/docs/src/src/interfaces/ISynthetix.sol/interface.IPerpsMarket.md b/docs/src/src/interfaces/ISynthetix.sol/interface.IPerpsMarket.md index d8b61de..2e1176b 100644 --- a/docs/src/src/interfaces/ISynthetix.sol/interface.IPerpsMarket.md +++ b/docs/src/src/interfaces/ISynthetix.sol/interface.IPerpsMarket.md @@ -1,5 +1,5 @@ # IPerpsMarket -[Git Source](https://github.com/moss-eth/zap/blob/59cf0756a77f382e301eda36c7e1793c595fd9b7/src/interfaces/ISynthetix.sol) +[Git Source](https://github.com/moss-eth/zap/blob/7ecc5cc79642d99fe6248a4895ed17a8ea025990/src/interfaces/ISynthetix.sol) ## Functions @@ -50,3 +50,18 @@ function payDebt(uint128 accountId, uint256 amount) external; function debt(uint128 accountId) external view returns (uint256 accountDebt); ``` +## Errors +### InsufficientCollateralAvailableForWithdraw + +```solidity +error InsufficientCollateralAvailableForWithdraw( + int256 withdrawableMarginUsd, uint256 requestedMarginUsd +); +``` + +### PermissionDenied + +```solidity +error PermissionDenied(uint128 accountId, bytes32 permission, address target); +``` + diff --git a/docs/src/src/interfaces/ISynthetix.sol/interface.ISpotMarket.md b/docs/src/src/interfaces/ISynthetix.sol/interface.ISpotMarket.md index 5c16970..1518a45 100644 --- a/docs/src/src/interfaces/ISynthetix.sol/interface.ISpotMarket.md +++ b/docs/src/src/interfaces/ISynthetix.sol/interface.ISpotMarket.md @@ -1,5 +1,5 @@ # ISpotMarket -[Git Source](https://github.com/moss-eth/zap/blob/59cf0756a77f382e301eda36c7e1793c595fd9b7/src/interfaces/ISynthetix.sol) +[Git Source](https://github.com/moss-eth/zap/blob/7ecc5cc79642d99fe6248a4895ed17a8ea025990/src/interfaces/ISynthetix.sol) ## Functions diff --git a/docs/src/src/interfaces/IUniswap.sol/interface.IQuoter.md b/docs/src/src/interfaces/IUniswap.sol/interface.IQuoter.md index a0b258f..cc007fe 100644 --- a/docs/src/src/interfaces/IUniswap.sol/interface.IQuoter.md +++ b/docs/src/src/interfaces/IUniswap.sol/interface.IQuoter.md @@ -1,5 +1,5 @@ # IQuoter -[Git Source](https://github.com/moss-eth/zap/blob/59cf0756a77f382e301eda36c7e1793c595fd9b7/src/interfaces/IUniswap.sol) +[Git Source](https://github.com/moss-eth/zap/blob/7ecc5cc79642d99fe6248a4895ed17a8ea025990/src/interfaces/IUniswap.sol) ## Functions diff --git a/docs/src/src/interfaces/IUniswap.sol/interface.IRouter.md b/docs/src/src/interfaces/IUniswap.sol/interface.IRouter.md index b8f3f9c..feec9d1 100644 --- a/docs/src/src/interfaces/IUniswap.sol/interface.IRouter.md +++ b/docs/src/src/interfaces/IUniswap.sol/interface.IRouter.md @@ -1,5 +1,5 @@ # IRouter -[Git Source](https://github.com/moss-eth/zap/blob/59cf0756a77f382e301eda36c7e1793c595fd9b7/src/interfaces/IUniswap.sol) +[Git Source](https://github.com/moss-eth/zap/blob/7ecc5cc79642d99fe6248a4895ed17a8ea025990/src/interfaces/IUniswap.sol) ## Functions diff --git a/docs/src/src/interfaces/README.md b/docs/src/src/interfaces/README.md index 87a90dd..ef4109b 100644 --- a/docs/src/src/interfaces/README.md +++ b/docs/src/src/interfaces/README.md @@ -3,6 +3,7 @@ # Contents - [IPool](IAave.sol/interface.IPool.md) - [IERC20](IERC20.sol/interface.IERC20.md) +- [IERC4626](IERC4626.sol/interface.IERC4626.md) - [ISpotMarket](ISynthetix.sol/interface.ISpotMarket.md) - [IPerpsMarket](ISynthetix.sol/interface.IPerpsMarket.md) - [IRouter](IUniswap.sol/interface.IRouter.md) diff --git a/docs/src/src/utils/Errors.sol/contract.Errors.md b/docs/src/src/utils/Errors.sol/contract.Errors.md index b4d46cf..8997033 100644 --- a/docs/src/src/utils/Errors.sol/contract.Errors.md +++ b/docs/src/src/utils/Errors.sol/contract.Errors.md @@ -1,5 +1,5 @@ # Errors -[Git Source](https://github.com/moss-eth/zap/blob/59cf0756a77f382e301eda36c7e1793c595fd9b7/src/utils/Errors.sol) +[Git Source](https://github.com/moss-eth/zap/blob/7ecc5cc79642d99fe6248a4895ed17a8ea025990/src/utils/Errors.sol) **Author:** @jaredborders diff --git a/docs/src/src/utils/Flush.sol/contract.Flush.md b/docs/src/src/utils/Flush.sol/contract.Flush.md index 62cd9a8..fd6923f 100644 --- a/docs/src/src/utils/Flush.sol/contract.Flush.md +++ b/docs/src/src/utils/Flush.sol/contract.Flush.md @@ -1,5 +1,5 @@ # Flush -[Git Source](https://github.com/moss-eth/zap/blob/59cf0756a77f382e301eda36c7e1793c595fd9b7/src/utils/Flush.sol) +[Git Source](https://github.com/moss-eth/zap/blob/7ecc5cc79642d99fe6248a4895ed17a8ea025990/src/utils/Flush.sol) **Author:** @jaredborders @@ -7,12 +7,22 @@ ## State Variables ### PLUMBER +**Note:** +plumber: + ```solidity address public PLUMBER; ``` +### nominatedPlumber + +```solidity +address public nominatedPlumber; +``` + + ## Functions ### constructor @@ -25,6 +35,9 @@ constructor(address _plumber); flush dust out of the contract +**Note:** +plumber: is the only authorized caller + ```solidity function flush(address _token) external; @@ -36,15 +49,18 @@ function flush(address _token) external; |`_token`|`address`|address of token to flush| -### designatePlumber +### nominatePlumber -designate a new plumber +nominate a new plumber *zero address can be used to remove flush capability* +**Note:** +plumber: is the only authorized caller + ```solidity -function designatePlumber(address _newPlumber) external; +function nominatePlumber(address _newPlumber) external; ``` **Parameters** @@ -53,13 +69,28 @@ function designatePlumber(address _newPlumber) external; |`_newPlumber`|`address`|address of new plumber| +### acceptPlumberNomination + + +```solidity +function acceptPlumberNomination() external; +``` + ## Events -### PlumberDesignated -emitted when a new plumber is designated +### PlumberNominated +emitted when a new plumber is nominated + + +```solidity +event PlumberNominated(address plumber); +``` + +### PlumberNominationAccepted +emitted when a new plumber accepts nomination ```solidity -event PlumberDesignated(address plumber); +event PlumberNominationAccepted(address plumber); ``` ## Errors @@ -71,3 +102,11 @@ thrown when caller is not the plumber error OnlyPlumber(); ``` +### OnlyNominatedPlumber +thrown when caller is not nominated to be plumber + + +```solidity +error OnlyNominatedPlumber(); +``` + diff --git a/docs/src/src/utils/Reentrancy.sol/contract.Reentrancy.md b/docs/src/src/utils/Reentrancy.sol/contract.Reentrancy.md index b684527..15bf48f 100644 --- a/docs/src/src/utils/Reentrancy.sol/contract.Reentrancy.md +++ b/docs/src/src/utils/Reentrancy.sol/contract.Reentrancy.md @@ -1,5 +1,5 @@ # Reentrancy -[Git Source](https://github.com/moss-eth/zap/blob/59cf0756a77f382e301eda36c7e1793c595fd9b7/src/utils/Reentrancy.sol) +[Git Source](https://github.com/moss-eth/zap/blob/7ecc5cc79642d99fe6248a4895ed17a8ea025990/src/utils/Reentrancy.sol) **Authors:** @moss-eth, @jaredborders diff --git a/docs/src/src/utils/SafeTransferERC20.sol/library.SafeERC20.md b/docs/src/src/utils/SafeTransferERC20.sol/library.SafeERC20.md index fc0eaf6..cb1a9cf 100644 --- a/docs/src/src/utils/SafeTransferERC20.sol/library.SafeERC20.md +++ b/docs/src/src/utils/SafeTransferERC20.sol/library.SafeERC20.md @@ -1,5 +1,5 @@ # SafeERC20 -[Git Source](https://github.com/moss-eth/zap/blob/59cf0756a77f382e301eda36c7e1793c595fd9b7/src/utils/SafeTransferERC20.sol) +[Git Source](https://github.com/moss-eth/zap/blob/7ecc5cc79642d99fe6248a4895ed17a8ea025990/src/utils/SafeTransferERC20.sol) *Wrappers around ERC-20 operations that throw on failure (when the token contract returns false). Tokens that return no value (and instead revert or From cb41f3414fcdb9ecab0fd41de07b0bcada42185d Mon Sep 17 00:00:00 2001 From: Florian <123545417+Flocqst@users.noreply.github.com> Date: Fri, 14 Mar 2025 22:08:33 +0100 Subject: [PATCH 20/24] =?UTF-8?q?=F0=9F=91=B7=20add=20external=20functions?= =?UTF-8?q?=20for=20zapping=20USDX=20(#67)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 👷 add external functions for zapping USDX * 👷 _zapOutUSDx --- src/Zap.sol | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/src/Zap.sol b/src/Zap.sol index 3549cc6..47f76d8 100644 --- a/src/Zap.sol +++ b/src/Zap.sol @@ -136,6 +136,25 @@ contract Zap is Reentrancy, Errors, Flush(msg.sender) { zapped = _wrap(STATA, SSTATA_SPOT_ID, zapped, _minAmountOut); } + /// @notice zap USDC into USDx + /// @dev caller must grant USDC allowance to this contract + /// @param _amount amount of USDC to zap + /// @param _minAmountOut acceptable slippage for wrapping and selling + /// @param _receiver address to receive USDx + /// @return zapped amount of USDx received + function zapInUSDX( + uint256 _amount, + uint256 _minAmountOut, + address _receiver + ) + external + returns (uint256 zapped) + { + _pull(USDC, msg.sender, _amount); + zapped = _zapInUSDx(_amount, _minAmountOut); + _push(USDX, _receiver, zapped); + } + /// @dev allowance is assumed /// @dev following execution, this contract will hold the zapped USDx function _zapInUSDx( @@ -181,6 +200,25 @@ contract Zap is Reentrancy, Errors, Flush(msg.sender) { zapped = _redeemStata(zapped, address(this)); } + /// @notice zap USDx into USDC + /// @dev caller must grant USDx allowance to this contract + /// @param _amount amount of USDx to zap + /// @param _minAmountOut acceptable slippage for buying and unwrapping + /// @param _receiver address to receive USDC + /// @return zapped amount of USDC received + function zapOutUSDX( + uint256 _amount, + uint256 _minAmountOut, + address _receiver + ) + external + returns (uint256 zapped) + { + _pull(USDX, msg.sender, _amount); + zapped = _zapOutUSDx(_amount, _minAmountOut); + _push(USDC, _receiver, zapped); + } + /// @dev allowance is assumed /// @dev following execution, this contract will hold the zapped USDC function _zapOutUSDx( @@ -190,8 +228,8 @@ contract Zap is Reentrancy, Errors, Flush(msg.sender) { internal returns (uint256 zapped) { - zapped = _buy(SSTATA_SPOT_ID, _amount, _minAmountOut); - zapped = _unwrap(SSTATA_SPOT_ID, zapped, _minAmountOut); + zapped = _buy(SUSDC_SPOT_ID, _amount, _minAmountOut); + zapped = _unwrap(SUSDC_SPOT_ID, zapped, _minAmountOut); } /*////////////////////////////////////////////////////////////// From 2598226c9bce76a6ab3d62ca0dd597be9ddea2b0 Mon Sep 17 00:00:00 2001 From: Moss Date: Mon, 24 Mar 2025 21:39:18 -0400 Subject: [PATCH 21/24] fixed todo --- test/EndToEnd.t.sol | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/EndToEnd.t.sol b/test/EndToEnd.t.sol index a46f9eb..08564bb 100644 --- a/test/EndToEnd.t.sol +++ b/test/EndToEnd.t.sol @@ -131,14 +131,14 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { zap = new Zap({ _usdc: address(usdc), _usdx: address(usdx), - _sstata: address(0), // no stata on base + _sstata: address(0), // TODO _spotMarket: address(spotMarket), _perpsMarket: address(perpsMarket), _referrer: BASE_REFERRER, _susdcSpotId: synthMarketId, - _sstataSpotId: 0, // no stata on base + _sstataSpotId: 0, // TODO _aave: BASE_AAVE_POOL, - _stata: address(0), // no stata on base + _stata: address(0), // TODO _router: BASE_ROUTER }); From 6e847736cf340c128749df85f28880a01941eaa2 Mon Sep 17 00:00:00 2001 From: Flocqst Date: Wed, 26 Mar 2025 12:28:33 +0100 Subject: [PATCH 22/24] =?UTF-8?q?=F0=9F=91=B7=20standardize=20USDx=20refer?= =?UTF-8?q?ences=20to=20sUSD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Zap.sol | 116 ++++++++++++++++++++++++++-------------------------- 1 file changed, 58 insertions(+), 58 deletions(-) diff --git a/src/Zap.sol b/src/Zap.sol index 47f76d8..1888945 100644 --- a/src/Zap.sol +++ b/src/Zap.sol @@ -12,7 +12,7 @@ import {Reentrancy} from "./utils/Reentrancy.sol"; import {SafeERC20} from "./utils/SafeTransferERC20.sol"; /// @title zap -/// @custom:synthetix zap USDC into and out of USDx +/// @custom:synthetix zap USDC into and out of both sUSD and STATA /// @custom:aave flash loan USDC to unwind synthetix collateral /// @custom:odos swap unwound collateral for USDC to repay flashloan /// @dev idle token balances are not safe @@ -30,8 +30,8 @@ contract Zap is Reentrancy, Errors, Flush(msg.sender) { /// @custom:synthetix bytes32 public constant MODIFY_PERMISSION = "PERPS_MODIFY_COLLATERAL"; bytes32 public constant BURN_PERMISSION = "BURN"; - uint128 public immutable USDX_ID; - address public immutable USDX; + uint128 public immutable SUSD_ID; + address public immutable SUSD; address public immutable SPOT_MARKET; address public immutable PERPS_MARKET; address public immutable REFERRER; @@ -49,7 +49,7 @@ contract Zap is Reentrancy, Errors, Flush(msg.sender) { constructor( address _usdc, - address _usdx, + address _susd, address _sstata, address _spotMarket, address _perpsMarket, @@ -64,7 +64,7 @@ contract Zap is Reentrancy, Errors, Flush(msg.sender) { USDC = _usdc; /// @custom:synthetix - USDX = _usdx; + SUSD = _susd; SSTATA = _sstata; SPOT_MARKET = _spotMarket; PERPS_MARKET = _perpsMarket; @@ -136,13 +136,13 @@ contract Zap is Reentrancy, Errors, Flush(msg.sender) { zapped = _wrap(STATA, SSTATA_SPOT_ID, zapped, _minAmountOut); } - /// @notice zap USDC into USDx + /// @notice zap USDC into sUSD /// @dev caller must grant USDC allowance to this contract /// @param _amount amount of USDC to zap /// @param _minAmountOut acceptable slippage for wrapping and selling - /// @param _receiver address to receive USDx - /// @return zapped amount of USDx received - function zapInUSDX( + /// @param _receiver address to receive sUSD + /// @return zapped amount of sUSD received + function zapInSUSD( uint256 _amount, uint256 _minAmountOut, address _receiver @@ -151,13 +151,13 @@ contract Zap is Reentrancy, Errors, Flush(msg.sender) { returns (uint256 zapped) { _pull(USDC, msg.sender, _amount); - zapped = _zapInUSDx(_amount, _minAmountOut); - _push(USDX, _receiver, zapped); + zapped = _zapInSUSD(_amount, _minAmountOut); + _push(SUSD, _receiver, zapped); } /// @dev allowance is assumed - /// @dev following execution, this contract will hold the zapped USDx - function _zapInUSDx( + /// @dev following execution, this contract will hold the zapped sUSD + function _zapInSUSD( uint256 _amount, uint256 _minAmountOut ) @@ -168,9 +168,9 @@ contract Zap is Reentrancy, Errors, Flush(msg.sender) { zapped = _sell(SUSDC_SPOT_ID, zapped, _minAmountOut); } - /// @notice zap USDx into USDC - /// @dev caller must grant USDx allowance to this contract - /// @param _amount amount of USDx to zap + /// @notice zap sStataUSDC into USDC + /// @dev caller must grant STATA allowance to this contract + /// @param _amount amount of STATA to zap /// @param _minAmountOut acceptable slippage for buying and unwrapping /// @param _receiver address to receive USDC /// @return zapped amount of USDC received @@ -200,13 +200,13 @@ contract Zap is Reentrancy, Errors, Flush(msg.sender) { zapped = _redeemStata(zapped, address(this)); } - /// @notice zap USDx into USDC - /// @dev caller must grant USDx allowance to this contract - /// @param _amount amount of USDx to zap + /// @notice zap sUSD into USDC + /// @dev caller must grant sUSD allowance to this contract + /// @param _amount amount of sUSD to zap /// @param _minAmountOut acceptable slippage for buying and unwrapping /// @param _receiver address to receive USDC /// @return zapped amount of USDC received - function zapOutUSDX( + function zapOutSUSD( uint256 _amount, uint256 _minAmountOut, address _receiver @@ -214,14 +214,14 @@ contract Zap is Reentrancy, Errors, Flush(msg.sender) { external returns (uint256 zapped) { - _pull(USDX, msg.sender, _amount); - zapped = _zapOutUSDx(_amount, _minAmountOut); + _pull(SUSD, msg.sender, _amount); + zapped = _zapOutSUSD(_amount, _minAmountOut); _push(USDC, _receiver, zapped); } /// @dev allowance is assumed /// @dev following execution, this contract will hold the zapped USDC - function _zapOutUSDx( + function _zapOutSUSD( uint256 _amount, uint256 _minAmountOut ) @@ -363,9 +363,9 @@ contract Zap is Reentrancy, Errors, Flush(msg.sender) { //////////////////////////////////////////////////////////////*/ /// @notice buy synth via synthetix spot market - /// @dev caller must grant USDX allowance to this contract + /// @dev caller must grant sUSD allowance to this contract /// @param _synthId synthetix market id of synth to buy - /// @param _amount amount of USDX to spend + /// @param _amount amount of sUSD to spend /// @param _minAmountOut acceptable slippage for buying /// @param _receiver address to receive synth /// @return received amount of synth @@ -379,7 +379,7 @@ contract Zap is Reentrancy, Errors, Flush(msg.sender) { returns (uint256 received, address synth) { synth = ISpotMarket(SPOT_MARKET).getSynth(_synthId); - _pull(USDX, msg.sender, _amount); + _pull(SUSD, msg.sender, _amount); received = _buy(_synthId, _amount, _minAmountOut); _push(synth, _receiver, received); } @@ -394,7 +394,7 @@ contract Zap is Reentrancy, Errors, Flush(msg.sender) { internal returns (uint256 received) { - IERC20(USDX).approve(SPOT_MARKET, _amount); + IERC20(SUSD).approve(SPOT_MARKET, _amount); (received,) = ISpotMarket(SPOT_MARKET).buy({ marketId: _synthId, usdAmount: _amount, @@ -408,8 +408,8 @@ contract Zap is Reentrancy, Errors, Flush(msg.sender) { /// @param _synthId synthetix market id of synth to sell /// @param _amount amount of synth to sell /// @param _minAmountOut acceptable slippage for selling - /// @param _receiver address to receive USDX - /// @return received amount of USDX + /// @param _receiver address to receive sUSD + /// @return received amount of sUSD function sell( uint128 _synthId, uint256 _amount, @@ -422,11 +422,11 @@ contract Zap is Reentrancy, Errors, Flush(msg.sender) { address synth = ISpotMarket(SPOT_MARKET).getSynth(_synthId); _pull(synth, msg.sender, _amount); received = _sell(_synthId, _amount, _minAmountOut); - _push(USDX, _receiver, received); + _push(SUSD, _receiver, received); } /// @dev allowance is assumed - /// @dev following execution, this contract will hold the sold USDX + /// @dev following execution, this contract will hold the sold sUSD function _sell( uint128 _synthId, uint256 _amount, @@ -589,23 +589,23 @@ contract Zap is Reentrancy, Errors, Flush(msg.sender) { ) ); - // zap USDC from flashloan into USDx; - // ALL USDC flashloaned from Aave is zapped into USDx - uint256 usdxAmount = _zapInUSDx(_flashloan, _zapMinAmountOut); + // zap USDC from flashloan into sUSD; + // ALL USDC flashloaned from Aave is zapped into sUSD + uint256 sUsdAmount = _zapInSUSD(_flashloan, _zapMinAmountOut); - // burn USDx to pay off synthetix perp position debt; - // debt is denominated in USD and thus repaid with USDx - _burn(usdxAmount, _accountId); + // burn sUSD to pay off synthetix perp position debt; + // debt is denominated in USD and thus repaid with sUSD + _burn(sUsdAmount, _accountId); - /// @dev given the USDC buffer, an amount of USDx + /// @dev given the USDC buffer, an amount of sUSD /// necessarily less than the buffer will remain (<$1); /// this amount is captured by the protocol // withdraw synthetix perp position collateral to this contract; // i.e., # of sETH, # of sUSDe, # of sUSDC (...) _withdraw(_collateralId, _collateralAmount, _accountId); - if (_collateral == USDC && _collateralId == USDX_ID) { - unwound = _zapOutUSDx(_collateralAmount, _collateralAmount / 1e12); + if (_collateral == USDC && _collateralId == SUSD_ID) { + unwound = _zapOutSUSD(_collateralAmount, _collateralAmount / 1e12); } else if (_collateral == STATA && _collateralId == SSTATA_SPOT_ID) { unwound = _zapOut(_collateralAmount, _unwrapMinAmountOut); } else { @@ -655,13 +655,13 @@ contract Zap is Reentrancy, Errors, Flush(msg.sender) { // determine amount of debt associated with synthetix perp position amount = IPerpsMarket(PERPS_MARKET).debt(_accountId); - uint256 usdxDecimals = IERC20(USDX).decimals(); + uint256 sUsdDecimals = IERC20(SUSD).decimals(); uint256 usdcDecimals = IERC20(USDC).decimals(); - /// @custom:synthetix debt is denominated in USDx + /// @custom:synthetix debt is denominated in sUSD /// @custom:aave debt is denominated in USDC /// @dev scale loan amount accordingly - amount /= 10 ** (usdxDecimals - usdcDecimals); + amount /= 10 ** (sUsdDecimals - usdcDecimals); /// @dev barring exceptional circumstances, /// a 1 USD buffer is sufficient to circumvent @@ -673,13 +673,13 @@ contract Zap is Reentrancy, Errors, Flush(msg.sender) { BURN //////////////////////////////////////////////////////////////*/ - /// @notice burn USDx to pay off synthetix perp position debt - /// @custom:caution ALL USDx remaining post-burn will be sent to the caller - /// @dev caller must grant USDX allowance to this contract - /// @dev excess USDx will be returned to the caller - /// @param _amount amount of USDx to burn + /// @notice burn sUSD to pay off synthetix perp position debt + /// @custom:caution ALL sUSD remaining post-burn will be sent to the caller + /// @dev caller must grant sUSD allowance to this contract + /// @dev excess sUSD will be returned to the caller + /// @param _amount amount of sUSD to burn /// @param _accountId synthetix perp market account id - /// @return excess amount of USDx returned to the caller + /// @return excess amount of sUSD returned to the caller function burn( uint256 _amount, uint128 _accountId @@ -687,23 +687,23 @@ contract Zap is Reentrancy, Errors, Flush(msg.sender) { external returns (uint256 excess) { - excess = IERC20(USDX).balanceOf(address(this)); + excess = IERC20(SUSD).balanceOf(address(this)); // pull and burn - _pull(USDX, msg.sender, _amount); + _pull(SUSD, msg.sender, _amount); _burn(_amount, _accountId); - excess = IERC20(USDX).balanceOf(address(this)) - excess; + excess = IERC20(SUSD).balanceOf(address(this)) - excess; - if (excess > 0) _push(USDX, msg.sender, excess); + if (excess > 0) _push(SUSD, msg.sender, excess); } /// @dev allowance is assumed - /// @dev following execution, this contract will hold any excess USDx + /// @dev following execution, this contract will hold any excess sUSD function _burn(uint256 _amount, uint128 _accountId) internal { - IERC20(USDX).approve(PERPS_MARKET, _amount); + IERC20(SUSD).approve(PERPS_MARKET, _amount); IPerpsMarket(PERPS_MARKET).payDebt(_accountId, _amount); - IERC20(USDX).approve(PERPS_MARKET, 0); + IERC20(SUSD).approve(PERPS_MARKET, 0); } /*////////////////////////////////////////////////////////////// @@ -726,8 +726,8 @@ contract Zap is Reentrancy, Errors, Flush(msg.sender) { isAuthorized(_accountId) { _withdraw(_synthId, _amount, _accountId); - address synth = _synthId == USDX_ID - ? USDX + address synth = _synthId == SUSD_ID + ? SUSD : ISpotMarket(SPOT_MARKET).getSynth(_synthId); _push(synth, _receiver, _amount); } From e791d51862aa899d3777ff28bb0bc6d455b777fb Mon Sep 17 00:00:00 2001 From: Flocqst Date: Wed, 26 Mar 2025 12:29:34 +0100 Subject: [PATCH 23/24] =?UTF-8?q?=F0=9F=9A=80=20standardize=20USDx=20refer?= =?UTF-8?q?ences=20to=20sUSD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- script/Deploy.s.sol | 8 ++++---- script/utils/Parameters.sol | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/script/Deploy.s.sol b/script/Deploy.s.sol index 2ecd67c..4e46a9a 100644 --- a/script/Deploy.s.sol +++ b/script/Deploy.s.sol @@ -19,7 +19,7 @@ contract Deploy is Script { function deploySystem( address usdc, - address usdx, + address susd, address sstata, address spotMarket, address perpsMarket, @@ -35,7 +35,7 @@ contract Deploy is Script { { zap = new Zap({ _usdc: usdc, - _usdx: usdx, + _susd: susd, _sstata: sstata, _spotMarket: spotMarket, _perpsMarket: perpsMarket, @@ -56,7 +56,7 @@ contract DeployBase is Deploy, Base { function run() public broadcast { Zap zap = deploySystem({ usdc: BASE_USDC, - usdx: BASE_USDX, + susd: BASE_SUSD, sstata: BASE_SSTATA, spotMarket: BASE_SPOT_MARKET, perpsMarket: BASE_PERPS_MARKET, @@ -79,7 +79,7 @@ contract DeployBaseSepolia is Deploy, BaseSepolia { function run() public broadcast { Zap zap = deploySystem({ usdc: BASE_SEPOLIA_USDC, - usdx: BASE_SEPOLIA_USDX, + susd: BASE_SEPOLIA_SUSD, sstata: address(0), //todo we are not deploying this stata release // to base spotMarket: BASE_SEPOLIA_SPOT_MARKET, diff --git a/script/utils/Parameters.sol b/script/utils/Parameters.sol index 295deca..65b583d 100644 --- a/script/utils/Parameters.sol +++ b/script/utils/Parameters.sol @@ -8,7 +8,7 @@ contract Base { /// @custom:synthetix address BASE_USDC = 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913; - address BASE_USDX = 0x09d51516F38980035153a554c26Df3C6f51a23C3; + address BASE_SUSD = 0x09d51516F38980035153a554c26Df3C6f51a23C3; address BASE_SSTATA = 0x729Ef31D86d31440ecBF49f27F7cD7c16c6616d2; address BASE_SPOT_MARKET = 0x18141523403e2595D31b22604AcB8Fc06a4CaA61; address BASE_PERPS_MARKET = 0x0A2AF931eFFd34b81ebcc57E3d3c9B1E1dE1C9Ce; @@ -33,7 +33,7 @@ contract BaseSepolia { /// @custom:synthetix address BASE_SEPOLIA_USDC = 0x5dEaC602762362FE5f135FA5904351916053cF70; - address BASE_SEPOLIA_USDX = address(0); + address BASE_SEPOLIA_SUSD = address(0); address BASE_SEPOLIA_SPOT_MARKET = address(0); address BASE_SEPOLIA_PERPS_MARKET = address(0); address BASE_SEPOLIA_REFERRER = address(0); From 9e67f11d3e652bcbe7bea176e974d84053af4344 Mon Sep 17 00:00:00 2001 From: Flocqst Date: Wed, 26 Mar 2025 12:30:07 +0100 Subject: [PATCH 24/24] =?UTF-8?q?=E2=9C=85=20standardize=20USDx=20referenc?= =?UTF-8?q?es=20to=20sUSD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/Burn.t.sol | 8 +- test/Buy.t.sol | 6 +- test/EndToEnd.t.sol | 394 +++++++++++++++++++-------------------- test/Sell.t.sol | 6 +- test/Withdraw.t.sol | 8 +- test/utils/Bootstrap.sol | 10 +- 6 files changed, 216 insertions(+), 216 deletions(-) diff --git a/test/Burn.t.sol b/test/Burn.t.sol index 51589d8..5fddd56 100644 --- a/test/Burn.t.sol +++ b/test/Burn.t.sol @@ -18,7 +18,7 @@ contract BurnTest is Bootstrap { /// @custom:TODO // ///@notice passes at block 269_610_923 // function test_burn_base(uint32 amount) public base { -// IERC20 A_USDX = IERC20(BASE_USDX); +// IERC20 A_SUSD = IERC20(BASE_SUSD); // uint128 accountID = // 170_141_183_460_469_231_731_687_303_715_884_105_766; @@ -28,14 +28,14 @@ contract BurnTest is Bootstrap { // vm.assume(amount > 1e6 && amount <= debt); -// uint256 balBefore = A_USDX.balanceOf(accountOwner); +// uint256 balBefore = A_SUSD.balanceOf(accountOwner); // vm.startPrank(accountOwner); -// A_USDX.approve(address(zap), type(uint256).max); +// A_SUSD.approve(address(zap), type(uint256).max); // zap.burn(amount, accountID); -// uint256 balAfter = A_USDX.balanceOf(accountOwner); +// uint256 balAfter = A_SUSD.balanceOf(accountOwner); // uint256 debtAfter = IPerpsMarket(zap.PERPS_MARKET()).debt(accountID); // assertEq(balAfter, balBefore - amount); diff --git a/test/Buy.t.sol b/test/Buy.t.sol index 3bc38a6..a0517fe 100644 --- a/test/Buy.t.sol +++ b/test/Buy.t.sol @@ -15,8 +15,8 @@ import { contract BuyTest is Bootstrap { function test_buy_base(uint32 amount) public base { - _spin(ACTOR, usdx, amount, address(zap)); - assertEq(usdx.balanceOf(ACTOR), amount); + _spin(ACTOR, susd, amount, address(zap)); + assertEq(susd.balanceOf(ACTOR), amount); assertEq(susdc.balanceOf(ACTOR), 0); vm.startPrank(ACTOR); (uint256 received, address synth) = zap.buy({ @@ -28,7 +28,7 @@ contract BuyTest is Bootstrap { vm.stopPrank(); assertEq(synth, address(susdc)); assertGe(received, DEFAULT_MIN_AMOUNT_OUT); - assertEq(usdx.balanceOf(ACTOR), 0); + assertEq(susd.balanceOf(ACTOR), 0); assertGe(susdc.balanceOf(ACTOR), DEFAULT_MIN_AMOUNT_OUT); } diff --git a/test/EndToEnd.t.sol b/test/EndToEnd.t.sol index 08564bb..4b50a57 100644 --- a/test/EndToEnd.t.sol +++ b/test/EndToEnd.t.sol @@ -66,7 +66,7 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { IERC20 usdc; IERC20 susdc; - IERC20 usdx; + IERC20 susd; IERC20 weth; uint128 smallAccountIdNoOi = @@ -120,7 +120,7 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { perpsMarket = IPerpsMarket(BASE_PERPS_MARKET); usdc = IERC20(BASE_USDC); - usdx = IERC20(BASE_USDX); + susd = IERC20(BASE_SUSD); weth = IERC20(BASE_WETH); uint128 synthMarketId = BASE_SUSDC_SPOT_MARKET_ID; @@ -130,7 +130,7 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { // create Zap contract to use actual sUSDC synth zap = new Zap({ _usdc: address(usdc), - _usdx: address(usdx), + _susd: address(susd), _sstata: address(0), // TODO _spotMarket: address(spotMarket), _perpsMarket: address(perpsMarket), @@ -223,7 +223,7 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { assertEq(weth.balanceOf(address(zap)), 0); assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); + assertEq(susd.balanceOf(address(zap)), 0); } function testOdosSwapMedium_Success() public selectFork(FORK["1_zap"]) { @@ -247,7 +247,7 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { assertEq(weth.balanceOf(address(zap)), 0); assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); + assertEq(susd.balanceOf(address(zap)), 0); } function testOdosSwapLarge_Success() public selectFork(FORK["10_zap"]) { @@ -271,7 +271,7 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { assertEq(weth.balanceOf(address(zap)), 0); assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); + assertEq(susd.balanceOf(address(zap)), 0); } // this test fails because unspent input asset is not refunded @@ -297,7 +297,7 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { assertEq(weth.balanceOf(address(zap)), 0); assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); + assertEq(susd.balanceOf(address(zap)), 0); vm.startPrank(user); weth.approve(address(zap), amount); @@ -312,7 +312,7 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { assertEq(weth.balanceOf(address(zap)), 0); assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); + assertEq(susd.balanceOf(address(zap)), 0); } function testOdosSwapSendToWrongAddress_Fail() @@ -339,7 +339,7 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { assertEq(weth.balanceOf(address(zap)), 0); assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); + assertEq(susd.balanceOf(address(zap)), 0); } function testOdosSwapSendToContract_Reentrancy_Success() @@ -435,7 +435,7 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { assertEq(weth.balanceOf(address(zap)), 0); assertEq(usdc.balanceOf(address(zap)), 0); - assertLt(usdx.balanceOf(address(zap)), 1 ether); + assertLt(susd.balanceOf(address(zap)), 1 ether); } function testUnwindSmallDebtWithOI_OverPay_AccountOwner_Success() @@ -499,7 +499,7 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { assertEq(weth.balanceOf(address(zap)), 0); assertEq(usdc.balanceOf(address(zap)), 0); - assertLt(usdx.balanceOf(address(zap)), 1 ether); + assertLt(susd.balanceOf(address(zap)), 1 ether); } function testUnwindSmallDebtNoOI_Underpay_AccountOwner_Fail() @@ -552,7 +552,7 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { assertEq(weth.balanceOf(address(zap)), 0); assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); + assertEq(susd.balanceOf(address(zap)), 0); } function testUnwindSmallDebtNoOI_Overpay_AccountOwner_OdosToWrongAddress_Fail( @@ -606,7 +606,7 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { assertEq(weth.balanceOf(address(zap)), 0); assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); + assertEq(susd.balanceOf(address(zap)), 0); } error NotPermitted(); @@ -661,7 +661,7 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { assertEq(weth.balanceOf(address(zap)), 0); assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); + assertEq(susd.balanceOf(address(zap)), 0); } function testUnwindSmallDebtNoOI_ZapNotPermitted_Fail() @@ -717,7 +717,7 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { assertEq(weth.balanceOf(address(zap)), 0); assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); + assertEq(susd.balanceOf(address(zap)), 0); } error OnlyAave(address); @@ -801,7 +801,7 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { assertEq(weth.balanceOf(address(zap)), 0); assertEq(usdc.balanceOf(address(zap)), 0); - assertLt(usdx.balanceOf(address(zap)), 1 ether); + assertLt(susd.balanceOf(address(zap)), 1 ether); } function testUnwindLargeDebtWithOI_OverPay_AccountOwner_Success() @@ -864,7 +864,7 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { assertEq(weth.balanceOf(address(zap)), 0); assertEq(usdc.balanceOf(address(zap)), 0); - assertLt(usdx.balanceOf(address(zap)), 1 ether); + assertLt(susd.balanceOf(address(zap)), 1 ether); } function testBurnSmallDebtNoOI_Exact_AccountOwner_Success() @@ -879,20 +879,20 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { uint256 amount = debt; - _spin(accountOwner, usdx, amount); - uint256 balanceBefore = usdx.balanceOf(accountOwner); + _spin(accountOwner, susd, amount); + uint256 balanceBefore = susd.balanceOf(accountOwner); vm.startPrank(accountOwner); - usdx.approve(address(zap), amount); + susd.approve(address(zap), amount); zap.burn(amount, accountId); vm.stopPrank(); assertEq(perpsMarket.debt(accountId), 0); - assertEq(usdx.balanceOf(accountOwner), balanceBefore - debt); + assertEq(susd.balanceOf(accountOwner), balanceBefore - debt); assertEq(weth.balanceOf(address(zap)), 0); assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); + assertEq(susd.balanceOf(address(zap)), 0); } function testBurnSmallDebtNoOI_Exact_NotAccountOwner_Success() @@ -907,20 +907,20 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { uint256 amount = debt; - _spin(user, usdx, amount); - uint256 balanceBefore = usdx.balanceOf(user); + _spin(user, susd, amount); + uint256 balanceBefore = susd.balanceOf(user); vm.startPrank(user); - usdx.approve(address(zap), amount); + susd.approve(address(zap), amount); zap.burn(amount, accountId); vm.stopPrank(); assertEq(perpsMarket.debt(accountId), 0); - assertEq(usdx.balanceOf(user), balanceBefore - debt); + assertEq(susd.balanceOf(user), balanceBefore - debt); assertEq(weth.balanceOf(address(zap)), 0); assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); + assertEq(susd.balanceOf(address(zap)), 0); } function testBurnSmallDebtNoOI_Overpay_AccountOwner_Success() @@ -935,21 +935,21 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { uint256 amount = 123_456_789 + debt; - _spin(accountOwner, usdx, amount); - uint256 balanceBefore = usdx.balanceOf(accountOwner); + _spin(accountOwner, susd, amount); + uint256 balanceBefore = susd.balanceOf(accountOwner); vm.startPrank(accountOwner); - usdx.approve(address(zap), amount); + susd.approve(address(zap), amount); zap.burn(amount, accountId); vm.stopPrank(); assertEq(perpsMarket.debt(accountId), 0); - assertEq(usdx.balanceOf(accountOwner), balanceBefore - debt); - assertEq(usdx.balanceOf(accountOwner), 123_456_789); + assertEq(susd.balanceOf(accountOwner), balanceBefore - debt); + assertEq(susd.balanceOf(accountOwner), 123_456_789); assertEq(weth.balanceOf(address(zap)), 0); assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); + assertEq(susd.balanceOf(address(zap)), 0); } function testBurnSmallDebtNoOI_Overpay_NotAccountOwner_Success() @@ -964,21 +964,21 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { uint256 amount = 123_456_789 + debt; - _spin(user, usdx, amount); - uint256 balanceBefore = usdx.balanceOf(user); + _spin(user, susd, amount); + uint256 balanceBefore = susd.balanceOf(user); vm.startPrank(user); - usdx.approve(address(zap), amount); + susd.approve(address(zap), amount); zap.burn(amount, accountId); vm.stopPrank(); assertEq(perpsMarket.debt(accountId), 0); - assertEq(usdx.balanceOf(user), balanceBefore - debt); - assertEq(usdx.balanceOf(user), 123_456_789); + assertEq(susd.balanceOf(user), balanceBefore - debt); + assertEq(susd.balanceOf(user), 123_456_789); assertEq(weth.balanceOf(address(zap)), 0); assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); + assertEq(susd.balanceOf(address(zap)), 0); } function testBurnSmallDebtNoOI_Partial_AccountOwner_Success() @@ -993,20 +993,20 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { uint256 amount = debt - 1e6; - _spin(accountOwner, usdx, amount); - uint256 balanceBefore = usdx.balanceOf(accountOwner); + _spin(accountOwner, susd, amount); + uint256 balanceBefore = susd.balanceOf(accountOwner); vm.startPrank(accountOwner); - usdx.approve(address(zap), amount); + susd.approve(address(zap), amount); zap.burn(amount, accountId); vm.stopPrank(); assertEq(perpsMarket.debt(accountId), debt - balanceBefore); - assertEq(usdx.balanceOf(accountOwner), 0); + assertEq(susd.balanceOf(accountOwner), 0); assertEq(weth.balanceOf(address(zap)), 0); assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); + assertEq(susd.balanceOf(address(zap)), 0); } function testBurnSmallDebtNoOI_Partial_NotAccountOwner_Success() @@ -1021,20 +1021,20 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { uint256 amount = debt - 1e6; - _spin(user, usdx, amount); - uint256 balanceBefore = usdx.balanceOf(user); + _spin(user, susd, amount); + uint256 balanceBefore = susd.balanceOf(user); vm.startPrank(user); - usdx.approve(address(zap), amount); + susd.approve(address(zap), amount); zap.burn(amount, accountId); vm.stopPrank(); assertEq(perpsMarket.debt(accountId), debt - balanceBefore); - assertEq(usdx.balanceOf(user), 0); + assertEq(susd.balanceOf(user), 0); assertEq(weth.balanceOf(address(zap)), 0); assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); + assertEq(susd.balanceOf(address(zap)), 0); } function testBurnSmallDebtWithOI_Exact_AccountOwner_Success() @@ -1049,20 +1049,20 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { uint256 amount = debt; - _spin(accountOwner, usdx, amount); - uint256 balanceBefore = usdx.balanceOf(accountOwner); + _spin(accountOwner, susd, amount); + uint256 balanceBefore = susd.balanceOf(accountOwner); vm.startPrank(accountOwner); - usdx.approve(address(zap), amount); + susd.approve(address(zap), amount); zap.burn(amount, accountId); vm.stopPrank(); assertEq(perpsMarket.debt(accountId), 0); - assertEq(usdx.balanceOf(accountOwner), balanceBefore - debt); + assertEq(susd.balanceOf(accountOwner), balanceBefore - debt); assertEq(weth.balanceOf(address(zap)), 0); assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); + assertEq(susd.balanceOf(address(zap)), 0); } function testBurnSmallDebtWithOI_Exact_NotAccountOwner_Success() @@ -1077,20 +1077,20 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { uint256 amount = debt; - _spin(user, usdx, amount); - uint256 balanceBefore = usdx.balanceOf(user); + _spin(user, susd, amount); + uint256 balanceBefore = susd.balanceOf(user); vm.startPrank(user); - usdx.approve(address(zap), amount); + susd.approve(address(zap), amount); zap.burn(amount, accountId); vm.stopPrank(); assertEq(perpsMarket.debt(accountId), 0); - assertEq(usdx.balanceOf(user), balanceBefore - debt); + assertEq(susd.balanceOf(user), balanceBefore - debt); assertEq(weth.balanceOf(address(zap)), 0); assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); + assertEq(susd.balanceOf(address(zap)), 0); } function testBurnSmallDebtWithOI_Overpay_AccountOwner_Success() @@ -1105,21 +1105,21 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { uint256 amount = 123_456_789 + debt; - _spin(accountOwner, usdx, amount); - uint256 balanceBefore = usdx.balanceOf(accountOwner); + _spin(accountOwner, susd, amount); + uint256 balanceBefore = susd.balanceOf(accountOwner); vm.startPrank(accountOwner); - usdx.approve(address(zap), amount); + susd.approve(address(zap), amount); zap.burn(amount, accountId); vm.stopPrank(); assertEq(perpsMarket.debt(accountId), 0); - assertEq(usdx.balanceOf(accountOwner), balanceBefore - debt); - assertEq(usdx.balanceOf(accountOwner), 123_456_789); + assertEq(susd.balanceOf(accountOwner), balanceBefore - debt); + assertEq(susd.balanceOf(accountOwner), 123_456_789); assertEq(weth.balanceOf(address(zap)), 0); assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); + assertEq(susd.balanceOf(address(zap)), 0); } function testBurnSmallDebtWithOI_Overpay_NotAccountOwner_Success() @@ -1134,21 +1134,21 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { uint256 amount = 123_456_789 + debt; - _spin(user, usdx, amount); - uint256 balanceBefore = usdx.balanceOf(user); + _spin(user, susd, amount); + uint256 balanceBefore = susd.balanceOf(user); vm.startPrank(user); - usdx.approve(address(zap), amount); + susd.approve(address(zap), amount); zap.burn(amount, accountId); vm.stopPrank(); assertEq(perpsMarket.debt(accountId), 0); - assertEq(usdx.balanceOf(user), balanceBefore - debt); - assertEq(usdx.balanceOf(user), 123_456_789); + assertEq(susd.balanceOf(user), balanceBefore - debt); + assertEq(susd.balanceOf(user), 123_456_789); assertEq(weth.balanceOf(address(zap)), 0); assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); + assertEq(susd.balanceOf(address(zap)), 0); } function testBurnSmallDebtWithOI_Partial_AccountOwner_Success() @@ -1163,20 +1163,20 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { uint256 amount = debt - 1e6; - _spin(accountOwner, usdx, amount); - uint256 balanceBefore = usdx.balanceOf(accountOwner); + _spin(accountOwner, susd, amount); + uint256 balanceBefore = susd.balanceOf(accountOwner); vm.startPrank(accountOwner); - usdx.approve(address(zap), amount); + susd.approve(address(zap), amount); zap.burn(amount, accountId); vm.stopPrank(); assertEq(perpsMarket.debt(accountId), debt - balanceBefore); - assertEq(usdx.balanceOf(accountOwner), 0); + assertEq(susd.balanceOf(accountOwner), 0); assertEq(weth.balanceOf(address(zap)), 0); assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); + assertEq(susd.balanceOf(address(zap)), 0); } function testBurnSmallDebtWithOI_Partial_NotAccountOwner_Success() @@ -1191,20 +1191,20 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { uint256 amount = debt - 1e6; - _spin(user, usdx, amount); - uint256 balanceBefore = usdx.balanceOf(user); + _spin(user, susd, amount); + uint256 balanceBefore = susd.balanceOf(user); vm.startPrank(user); - usdx.approve(address(zap), amount); + susd.approve(address(zap), amount); zap.burn(amount, accountId); vm.stopPrank(); assertEq(perpsMarket.debt(accountId), debt - balanceBefore); - assertEq(usdx.balanceOf(user), 0); + assertEq(susd.balanceOf(user), 0); assertEq(weth.balanceOf(address(zap)), 0); assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); + assertEq(susd.balanceOf(address(zap)), 0); } function testBurnLargeDebtNoOI_Exact_AccountOwner_Success() @@ -1219,20 +1219,20 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { uint256 amount = debt; - _spin(accountOwner, usdx, amount); - uint256 balanceBefore = usdx.balanceOf(accountOwner); + _spin(accountOwner, susd, amount); + uint256 balanceBefore = susd.balanceOf(accountOwner); vm.startPrank(accountOwner); - usdx.approve(address(zap), amount); + susd.approve(address(zap), amount); zap.burn(amount, accountId); vm.stopPrank(); assertEq(perpsMarket.debt(accountId), 0); - assertEq(usdx.balanceOf(accountOwner), balanceBefore - debt); + assertEq(susd.balanceOf(accountOwner), balanceBefore - debt); assertEq(weth.balanceOf(address(zap)), 0); assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); + assertEq(susd.balanceOf(address(zap)), 0); } function testBurnLargeDebtNoOI_Exact_NotAccountOwner_Success() @@ -1247,20 +1247,20 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { uint256 amount = debt; - _spin(user, usdx, amount); - uint256 balanceBefore = usdx.balanceOf(user); + _spin(user, susd, amount); + uint256 balanceBefore = susd.balanceOf(user); vm.startPrank(user); - usdx.approve(address(zap), amount); + susd.approve(address(zap), amount); zap.burn(amount, accountId); vm.stopPrank(); assertEq(perpsMarket.debt(accountId), 0); - assertEq(usdx.balanceOf(user), balanceBefore - debt); + assertEq(susd.balanceOf(user), balanceBefore - debt); assertEq(weth.balanceOf(address(zap)), 0); assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); + assertEq(susd.balanceOf(address(zap)), 0); } function testBurnLargeDebtNoOI_Overpay_AccountOwner_Success() @@ -1275,21 +1275,21 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { uint256 amount = 123_456_789 + debt; - _spin(accountOwner, usdx, amount); - uint256 balanceBefore = usdx.balanceOf(accountOwner); + _spin(accountOwner, susd, amount); + uint256 balanceBefore = susd.balanceOf(accountOwner); vm.startPrank(accountOwner); - usdx.approve(address(zap), amount); + susd.approve(address(zap), amount); zap.burn(amount, accountId); vm.stopPrank(); assertEq(perpsMarket.debt(accountId), 0); - assertEq(usdx.balanceOf(accountOwner), balanceBefore - debt); - assertEq(usdx.balanceOf(accountOwner), 123_456_789); + assertEq(susd.balanceOf(accountOwner), balanceBefore - debt); + assertEq(susd.balanceOf(accountOwner), 123_456_789); assertEq(weth.balanceOf(address(zap)), 0); assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); + assertEq(susd.balanceOf(address(zap)), 0); } function testBurnLargeDebtNoOI_Overpay_NotAccountOwner_Success() @@ -1304,21 +1304,21 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { uint256 amount = 123_456_789 + debt; - _spin(user, usdx, amount); - uint256 balanceBefore = usdx.balanceOf(user); + _spin(user, susd, amount); + uint256 balanceBefore = susd.balanceOf(user); vm.startPrank(user); - usdx.approve(address(zap), amount); + susd.approve(address(zap), amount); zap.burn(amount, accountId); vm.stopPrank(); assertEq(perpsMarket.debt(accountId), 0); - assertEq(usdx.balanceOf(user), balanceBefore - debt); - assertEq(usdx.balanceOf(user), 123_456_789); + assertEq(susd.balanceOf(user), balanceBefore - debt); + assertEq(susd.balanceOf(user), 123_456_789); assertEq(weth.balanceOf(address(zap)), 0); assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); + assertEq(susd.balanceOf(address(zap)), 0); } function testBurnLargeDebtNoOI_Partial_AccountOwner_Success() @@ -1333,20 +1333,20 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { uint256 amount = debt - 1e6; - _spin(accountOwner, usdx, amount); - uint256 balanceBefore = usdx.balanceOf(accountOwner); + _spin(accountOwner, susd, amount); + uint256 balanceBefore = susd.balanceOf(accountOwner); vm.startPrank(accountOwner); - usdx.approve(address(zap), amount); + susd.approve(address(zap), amount); zap.burn(amount, accountId); vm.stopPrank(); assertEq(perpsMarket.debt(accountId), debt - balanceBefore); - assertEq(usdx.balanceOf(accountOwner), 0); + assertEq(susd.balanceOf(accountOwner), 0); assertEq(weth.balanceOf(address(zap)), 0); assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); + assertEq(susd.balanceOf(address(zap)), 0); } function testBurnLargeDebtNoOI_Partial_NotAccountOwner_Success() @@ -1361,20 +1361,20 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { uint256 amount = debt - 1e6; - _spin(user, usdx, amount); - uint256 balanceBefore = usdx.balanceOf(user); + _spin(user, susd, amount); + uint256 balanceBefore = susd.balanceOf(user); vm.startPrank(user); - usdx.approve(address(zap), amount); + susd.approve(address(zap), amount); zap.burn(amount, accountId); vm.stopPrank(); assertEq(perpsMarket.debt(accountId), debt - balanceBefore); - assertEq(usdx.balanceOf(user), 0); + assertEq(susd.balanceOf(user), 0); assertEq(weth.balanceOf(address(zap)), 0); assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); + assertEq(susd.balanceOf(address(zap)), 0); } function testBurnLargeDebtWithOI_Exact_AccountOwner_Success() @@ -1389,20 +1389,20 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { uint256 amount = debt; - _spin(accountOwner, usdx, amount); - uint256 balanceBefore = usdx.balanceOf(accountOwner); + _spin(accountOwner, susd, amount); + uint256 balanceBefore = susd.balanceOf(accountOwner); vm.startPrank(accountOwner); - usdx.approve(address(zap), amount); + susd.approve(address(zap), amount); zap.burn(amount, accountId); vm.stopPrank(); assertEq(perpsMarket.debt(accountId), 0); - assertEq(usdx.balanceOf(accountOwner), balanceBefore - debt); + assertEq(susd.balanceOf(accountOwner), balanceBefore - debt); assertEq(weth.balanceOf(address(zap)), 0); assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); + assertEq(susd.balanceOf(address(zap)), 0); } function testBurnLargeDebtWithOI_Exact_NotAccountOwner_Success() @@ -1417,20 +1417,20 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { uint256 amount = debt; - _spin(user, usdx, amount); - uint256 balanceBefore = usdx.balanceOf(user); + _spin(user, susd, amount); + uint256 balanceBefore = susd.balanceOf(user); vm.startPrank(user); - usdx.approve(address(zap), amount); + susd.approve(address(zap), amount); zap.burn(amount, accountId); vm.stopPrank(); assertEq(perpsMarket.debt(accountId), 0); - assertEq(usdx.balanceOf(user), balanceBefore - debt); + assertEq(susd.balanceOf(user), balanceBefore - debt); assertEq(weth.balanceOf(address(zap)), 0); assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); + assertEq(susd.balanceOf(address(zap)), 0); } function testBurnLargeDebtWithOI_Overpay_AccountOwner_Success() @@ -1445,21 +1445,21 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { uint256 amount = 123_456_789 + debt; - _spin(accountOwner, usdx, amount); - uint256 balanceBefore = usdx.balanceOf(accountOwner); + _spin(accountOwner, susd, amount); + uint256 balanceBefore = susd.balanceOf(accountOwner); vm.startPrank(accountOwner); - usdx.approve(address(zap), amount); + susd.approve(address(zap), amount); zap.burn(amount, accountId); vm.stopPrank(); assertEq(perpsMarket.debt(accountId), 0); - assertEq(usdx.balanceOf(accountOwner), balanceBefore - debt); - assertEq(usdx.balanceOf(accountOwner), 123_456_789); + assertEq(susd.balanceOf(accountOwner), balanceBefore - debt); + assertEq(susd.balanceOf(accountOwner), 123_456_789); assertEq(weth.balanceOf(address(zap)), 0); assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); + assertEq(susd.balanceOf(address(zap)), 0); } function testBurnLargeDebtWithOI_Overpay_NotAccountOwner_Success() @@ -1474,21 +1474,21 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { uint256 amount = 123_456_789 + debt; - _spin(user, usdx, amount); - uint256 balanceBefore = usdx.balanceOf(user); + _spin(user, susd, amount); + uint256 balanceBefore = susd.balanceOf(user); vm.startPrank(user); - usdx.approve(address(zap), amount); + susd.approve(address(zap), amount); zap.burn(amount, accountId); vm.stopPrank(); assertEq(perpsMarket.debt(accountId), 0); - assertEq(usdx.balanceOf(user), balanceBefore - debt); - assertEq(usdx.balanceOf(user), 123_456_789); + assertEq(susd.balanceOf(user), balanceBefore - debt); + assertEq(susd.balanceOf(user), 123_456_789); assertEq(weth.balanceOf(address(zap)), 0); assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); + assertEq(susd.balanceOf(address(zap)), 0); } function testBurnLargeDebtWithOI_Partial_AccountOwner_Success() @@ -1503,20 +1503,20 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { uint256 amount = debt - 1e6; - _spin(accountOwner, usdx, amount); - uint256 balanceBefore = usdx.balanceOf(accountOwner); + _spin(accountOwner, susd, amount); + uint256 balanceBefore = susd.balanceOf(accountOwner); vm.startPrank(accountOwner); - usdx.approve(address(zap), amount); + susd.approve(address(zap), amount); zap.burn(amount, accountId); vm.stopPrank(); assertEq(perpsMarket.debt(accountId), debt - balanceBefore); - assertEq(usdx.balanceOf(accountOwner), 0); + assertEq(susd.balanceOf(accountOwner), 0); assertEq(weth.balanceOf(address(zap)), 0); assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); + assertEq(susd.balanceOf(address(zap)), 0); } function testBurnLargeDebtWithOI_Partial_NotAccountOwner_Success() @@ -1531,54 +1531,54 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { uint256 amount = debt - 1e6; - _spin(user, usdx, amount); - uint256 balanceBefore = usdx.balanceOf(user); + _spin(user, susd, amount); + uint256 balanceBefore = susd.balanceOf(user); vm.startPrank(user); - usdx.approve(address(zap), amount); + susd.approve(address(zap), amount); zap.burn(amount, accountId); vm.stopPrank(); assertEq(perpsMarket.debt(accountId), debt - balanceBefore); - assertEq(usdx.balanceOf(user), 0); + assertEq(susd.balanceOf(user), 0); assertEq(weth.balanceOf(address(zap)), 0); assertEq(usdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); + assertEq(susd.balanceOf(address(zap)), 0); } // TODO fix plumber tests function testFlush_Plumber_Success() public selectFork(FORK["1_zap"]) { uint256 amountWeth = 1234 ether; - uint256 amountUsdx = 56_789 ether; + uint256 amountSusd = 56_789 ether; _spin(address(zap), weth, amountWeth); - _spin(address(zap), usdx, amountUsdx); + _spin(address(zap), susd, amountSusd); uint256 zapWethBefore = weth.balanceOf(address(zap)); - uint256 zapUsdxBefore = usdx.balanceOf(address(zap)); + uint256 zapSusdBefore = susd.balanceOf(address(zap)); uint256 plumberWethBefore = weth.balanceOf(address(this)); - uint256 plumberUsdxBefore = usdx.balanceOf(address(this)); + uint256 plumberSusdBefore = susd.balanceOf(address(this)); // this test contract created the Zap contract and should be the owner - zap.flush(address(usdx)); + zap.flush(address(susd)); - assertEq(usdx.balanceOf(address(zap)), 0); + assertEq(susd.balanceOf(address(zap)), 0); assertEq(weth.balanceOf(address(zap)), zapWethBefore); assertEq( - usdx.balanceOf(address(this)), plumberUsdxBefore + zapUsdxBefore + susd.balanceOf(address(this)), plumberSusdBefore + zapSusdBefore ); assertEq(weth.balanceOf(address(this)), plumberWethBefore); zap.flush(address(weth)); - assertEq(usdx.balanceOf(address(zap)), 0); + assertEq(susd.balanceOf(address(zap)), 0); assertEq(weth.balanceOf(address(zap)), 0); assertEq( - usdx.balanceOf(address(this)), plumberUsdxBefore + zapUsdxBefore + susd.balanceOf(address(this)), plumberSusdBefore + zapSusdBefore ); assertEq( weth.balanceOf(address(this)), plumberWethBefore + zapWethBefore @@ -1589,25 +1589,25 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { function testFlush_NotPlumberer_Fail() public selectFork(FORK["1_zap"]) { uint256 amountWeth = 1234 ether; - uint256 amountUsdx = 56_789 ether; + uint256 amountSusd = 56_789 ether; _spin(address(zap), weth, amountWeth); - _spin(address(zap), usdx, amountUsdx); + _spin(address(zap), susd, amountSusd); uint256 zapWethBefore = weth.balanceOf(address(zap)); - uint256 zapUsdxBefore = usdx.balanceOf(address(zap)); + uint256 zapSusdBefore = susd.balanceOf(address(zap)); uint256 plumberWethBefore = weth.balanceOf(address(this)); - uint256 plumberUsdxBefore = usdx.balanceOf(address(this)); + uint256 plumberSusdBefore = susd.balanceOf(address(this)); // this test contract created the Zap contract and should be the owner vm.prank(vm.addr(987_654_321)); vm.expectRevert(abi.encodeWithSelector(OnlyPlumber.selector)); - zap.flush(address(usdx)); + zap.flush(address(susd)); - assertEq(usdx.balanceOf(address(zap)), zapUsdxBefore); + assertEq(susd.balanceOf(address(zap)), zapSusdBefore); assertEq(weth.balanceOf(address(zap)), zapWethBefore); - assertEq(usdx.balanceOf(address(this)), plumberUsdxBefore); + assertEq(susd.balanceOf(address(this)), plumberSusdBefore); assertEq(weth.balanceOf(address(this)), plumberWethBefore); } @@ -1656,16 +1656,16 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { { address user = vm.addr(5); uint32 amount = 1_000_000_000; - _spin(user, usdx, amount); + _spin(user, susd, amount); vm.startPrank(user); uint128 accountId = perpsMarket.createAccount(); int128 margin = int128(int32(amount)); - usdx.approve(address(perpsMarket), amount); + susd.approve(address(perpsMarket), amount); perpsMarket.modifyCollateral(accountId, 0, margin); - assertEq(usdx.balanceOf(user), 0); + assertEq(susd.balanceOf(user), 0); assertEq(perpsMarket.totalCollateralValue(accountId), amount); perpsMarket.grantPermission( @@ -1679,12 +1679,12 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { }); vm.stopPrank(); - assertEq(usdx.balanceOf(user), amount); + assertEq(susd.balanceOf(user), amount); assertEq(perpsMarket.totalCollateralValue(accountId), 0); assertEq(usdc.balanceOf(address(zap)), 0); assertEq(susdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); + assertEq(susd.balanceOf(address(zap)), 0); assertFalse( perpsMarket.isAuthorized( accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) @@ -1698,16 +1698,16 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { { address user = vm.addr(5); uint32 amount = 1_000_000_000; - _spin(user, usdx, amount); + _spin(user, susd, amount); vm.startPrank(user); uint128 accountId = perpsMarket.createAccount(); int128 margin = int128(int32(amount)); - usdx.approve(address(perpsMarket), amount); + susd.approve(address(perpsMarket), amount); perpsMarket.modifyCollateral(accountId, 0, margin); - assertEq(usdx.balanceOf(user), 0); + assertEq(susd.balanceOf(user), 0); perpsMarket.grantPermission( accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) @@ -1722,12 +1722,12 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { _receiver: user }); - assertEq(usdx.balanceOf(user), 0); + assertEq(susd.balanceOf(user), 0); assertEq(perpsMarket.totalCollateralValue(accountId), amount); assertEq(usdc.balanceOf(address(zap)), 0); assertEq(susdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); + assertEq(susd.balanceOf(address(zap)), 0); assertTrue( perpsMarket.isAuthorized( accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) @@ -1741,16 +1741,16 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { { address user = vm.addr(5); uint32 amount = 1_000_000_000; - _spin(user, usdx, amount); + _spin(user, susd, amount); vm.startPrank(user); uint128 accountId = perpsMarket.createAccount(); int128 margin = int128(int32(amount)); - usdx.approve(address(perpsMarket), amount); + susd.approve(address(perpsMarket), amount); perpsMarket.modifyCollateral(accountId, 0, margin); - assertEq(usdx.balanceOf(user), 0); + assertEq(susd.balanceOf(user), 0); assertEq(perpsMarket.totalCollateralValue(accountId), amount); vm.expectRevert( @@ -1770,12 +1770,12 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { vm.stopPrank(); - assertEq(usdx.balanceOf(user), 0); + assertEq(susd.balanceOf(user), 0); assertEq(perpsMarket.totalCollateralValue(accountId), amount); assertEq(usdc.balanceOf(address(zap)), 0); assertEq(susdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); + assertEq(susd.balanceOf(address(zap)), 0); assertFalse( perpsMarket.isAuthorized( accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) @@ -1793,13 +1793,13 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { address user = vm.addr(1); // uint256 amount = 1000e6; - _spin(user, usdx, amount); + _spin(user, susd, amount); - assertEq(usdx.balanceOf(user), amount); + assertEq(susd.balanceOf(user), amount); assertEq(susdc.balanceOf(user), 0); vm.startPrank(user); - usdx.approve(address(zap), amount); + susd.approve(address(zap), amount); (uint256 received, address synth) = zap.buy({ _synthId: zap.SSTATA_SPOT_ID(), @@ -1811,12 +1811,12 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { assertEq(synth, address(susdc)); assertGe(received, amount * 9 / 10); - assertEq(usdx.balanceOf(user), 0); + assertEq(susd.balanceOf(user), 0); assertGe(susdc.balanceOf(user), amount * 9 / 10); assertEq(usdc.balanceOf(address(zap)), 0); assertEq(susdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); + assertEq(susd.balanceOf(address(zap)), 0); } function testSellSuccess( /*uint128 amount*/ ) @@ -1828,10 +1828,10 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { // vm.assume(amount < 1e20); uint256 amount = 1000e18; uint256 minAmountOut = amount * 99 / 100; - _spin(user, usdx, amount); + _spin(user, susd, amount); vm.startPrank(user); - usdx.approve(address(zap), amount); + susd.approve(address(zap), amount); (uint256 received,) = zap.buy({ _synthId: zap.SSTATA_SPOT_ID(), @@ -1840,7 +1840,7 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { _receiver: user }); - assertEq(usdx.balanceOf(user), 0); + assertEq(susd.balanceOf(user), 0); assertEq(usdc.balanceOf(user), 0); assertEq(susdc.balanceOf(user), received); assertGe(received, minAmountOut); @@ -1857,14 +1857,14 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { }); vm.stopPrank(); - assertGe(usdx.balanceOf(user), minAmountOut); + assertGe(susd.balanceOf(user), minAmountOut); assertGe(received, minAmountOut); - assertEq(usdx.balanceOf(user), received); + assertEq(susd.balanceOf(user), received); assertEq(susdc.balanceOf(user), 0); assertEq(usdc.balanceOf(address(zap)), 0); assertEq(susdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); + assertEq(susd.balanceOf(address(zap)), 0); } function testUnwrap( /* uint32 amount */ ) @@ -1907,7 +1907,7 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { assertEq(usdc.balanceOf(address(zap)), 0); assertEq(susdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); + assertEq(susd.balanceOf(address(zap)), 0); } function testWrap( /*uint64 amount*/ ) public selectFork(FORK["1_zap"]) { @@ -1936,7 +1936,7 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { assertEq(usdc.balanceOf(address(zap)), 0); assertEq(susdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); + assertEq(susd.balanceOf(address(zap)), 0); } function testZapInSuccess( /*uint64 amount*/ ) @@ -1948,7 +1948,7 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { _spin(user, usdc, amount); assertEq(usdc.balanceOf(user), amount); - assertEq(usdx.balanceOf(user), 0); + assertEq(susd.balanceOf(user), 0); vm.startPrank(user); usdc.approve(address(zap), amount); @@ -1959,11 +1959,11 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { assertGe(zapped, uint256(amount) * 99e10); // amount * 1e12 * 0.99 assertEq(usdc.balanceOf(user), 0); - assertEq(usdx.balanceOf(user), zapped); + assertEq(susd.balanceOf(user), zapped); assertEq(usdc.balanceOf(address(zap)), 0); assertEq(susdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); + assertEq(susd.balanceOf(address(zap)), 0); } function testZapOutSuccess( /*uint64 amount*/ ) @@ -1985,13 +1985,13 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { assertEq(usdc.balanceOf(address(this)), 0); assertEq(susdc.balanceOf(address(this)), amount); - _spin(user, usdx, amount); + _spin(user, susd, amount); assertEq(usdc.balanceOf(user), 0); - assertEq(usdx.balanceOf(user), amount); + assertEq(susd.balanceOf(user), amount); vm.startPrank(user); - usdx.approve(address(zap), amount); + susd.approve(address(zap), amount); uint256 zapped = zap.zapOut({ _amount: amount, @@ -2002,11 +2002,11 @@ contract EndToEndTest is Test, Base, Constants, OdosSwapData { assertGe(zapped * 1e12, amount * 9 / 10); assertEq(usdc.balanceOf(user), zapped); - assertEq(usdx.balanceOf(user), 0); + assertEq(susd.balanceOf(user), 0); assertEq(usdc.balanceOf(address(zap)), 0); assertEq(susdc.balanceOf(address(zap)), 0); - assertEq(usdx.balanceOf(address(zap)), 0); + assertEq(susd.balanceOf(address(zap)), 0); } } diff --git a/test/Sell.t.sol b/test/Sell.t.sol index ca86a70..7995809 100644 --- a/test/Sell.t.sol +++ b/test/Sell.t.sol @@ -15,7 +15,7 @@ import { contract SellTest is Bootstrap { function test_sell_base(uint32 amount) public base { - _spin(ACTOR, usdx, amount, address(zap)); + _spin(ACTOR, susd, amount, address(zap)); vm.startPrank(ACTOR); (uint256 received,) = zap.buy({ _synthId: zap.SUSDC_SPOT_ID(), @@ -23,7 +23,7 @@ contract SellTest is Bootstrap { _minAmountOut: DEFAULT_MIN_AMOUNT_OUT, _receiver: ACTOR }); - assertEq(usdx.balanceOf(ACTOR), 0); + assertEq(susd.balanceOf(ACTOR), 0); assertGe(susdc.balanceOf(ACTOR), DEFAULT_MIN_AMOUNT_OUT); susdc.approve(address(zap), type(uint256).max); received = zap.sell({ @@ -34,7 +34,7 @@ contract SellTest is Bootstrap { }); vm.stopPrank(); assertGe(received, DEFAULT_MIN_AMOUNT_OUT); - assertGe(usdx.balanceOf(ACTOR), DEFAULT_MIN_AMOUNT_OUT); + assertGe(susd.balanceOf(ACTOR), DEFAULT_MIN_AMOUNT_OUT); assertEq(susdc.balanceOf(ACTOR), 0); } diff --git a/test/Withdraw.t.sol b/test/Withdraw.t.sol index 7db8129..15fee9b 100644 --- a/test/Withdraw.t.sol +++ b/test/Withdraw.t.sol @@ -23,16 +23,16 @@ contract WithdrawTest is Bootstrap, Errors { function test_withdraw_base() public base { uint32 amount = 1_000_000_000; - _spin(ACTOR, usdx, amount, address(zap)); + _spin(ACTOR, susd, amount, address(zap)); vm.startPrank(ACTOR); uint128 accountId = perpsMarket.createAccount(); int128 margin = int128(int32(amount)); - usdx.approve(address(perpsMarket), type(uint256).max); + susd.approve(address(perpsMarket), type(uint256).max); perpsMarket.grantPermission( accountId, _PERPS_MODIFY_COLLATERAL_PERMISSION, address(zap) ); perpsMarket.modifyCollateral(accountId, 0, margin); - assertEq(usdx.balanceOf(ACTOR), 0); + assertEq(susd.balanceOf(ACTOR), 0); zap.withdraw({ _synthId: 0, _amount: amount, @@ -40,7 +40,7 @@ contract WithdrawTest is Bootstrap, Errors { _receiver: ACTOR }); vm.stopPrank(); - assertEq(usdx.balanceOf(ACTOR), amount); + assertEq(susd.balanceOf(ACTOR), amount); } } diff --git a/test/utils/Bootstrap.sol b/test/utils/Bootstrap.sol index 84cecf4..1ff5934 100644 --- a/test/utils/Bootstrap.sol +++ b/test/utils/Bootstrap.sol @@ -29,7 +29,7 @@ contract Bootstrap is Test, Deploy, Base, BaseSepolia, Constants { IPerpsMarket perpsMarket; IERC20 usdc; IERC20 susdc; - IERC20 usdx; + IERC20 susd; IERC20 sstata; IERC20 weth; IERC20 tbtc; @@ -54,7 +54,7 @@ contract Bootstrap is Test, Deploy, Base, BaseSepolia, Constants { /// @custom:target zap = deploySystem({ usdc: BASE_USDC, - usdx: BASE_USDX, + susd: BASE_SUSD, sstata: BASE_SSTATA, spotMarket: BASE_SPOT_MARKET, perpsMarket: BASE_PERPS_MARKET, @@ -71,7 +71,7 @@ contract Bootstrap is Test, Deploy, Base, BaseSepolia, Constants { perpsMarket = IPerpsMarket(BASE_PERPS_MARKET); usdc = IERC20(BASE_USDC); susdc = IERC20(spotMarket.getSynth(zap.SUSDC_SPOT_ID())); - usdx = IERC20(BASE_USDX); + susd = IERC20(BASE_SUSD); sstata = IERC20(BASE_SSTATA); weth = IERC20(BASE_WETH); tbtc = IERC20(BASE_TBTC); @@ -86,7 +86,7 @@ contract Bootstrap is Test, Deploy, Base, BaseSepolia, Constants { /// @custom:target zap = deploySystem({ usdc: BASE_SEPOLIA_USDC, - usdx: BASE_SEPOLIA_USDX, + susd: BASE_SEPOLIA_SUSD, sstata: address(0), //todo we are not deploying this stata release // to base spotMarket: BASE_SEPOLIA_SPOT_MARKET, @@ -106,7 +106,7 @@ contract Bootstrap is Test, Deploy, Base, BaseSepolia, Constants { perpsMarket = IPerpsMarket(BASE_SEPOLIA_PERPS_MARKET); usdc = IERC20(BASE_SEPOLIA_USDC); susdc = IERC20(spotMarket.getSynth(zap.SSTATA_SPOT_ID())); - usdx = IERC20(BASE_SEPOLIA_USDX); + susd = IERC20(BASE_SEPOLIA_SUSD); weth = IERC20(BASE_SEPOLIA_WETH); _;