From 43187e6e26223071f291c9af94db2453f2af169a Mon Sep 17 00:00:00 2001 From: YBM Date: Tue, 10 Sep 2024 18:01:54 -0500 Subject: [PATCH] test: declare new typehash specific for converter, init happy path sellAssetWithSig test --- src/test/TestGsmConverter.t.sol | 120 +++++++++++++++++++++++++++++--- src/test/helpers/Constants.sol | 10 +++ 2 files changed, 122 insertions(+), 8 deletions(-) diff --git a/src/test/TestGsmConverter.t.sol b/src/test/TestGsmConverter.t.sol index 1527cc94..6a05c564 100644 --- a/src/test/TestGsmConverter.t.sol +++ b/src/test/TestGsmConverter.t.sol @@ -337,8 +337,112 @@ contract TestGsmConverter is TestGhoBase { gsmConverter.sellAsset(DEFAULT_GSM_BUIDL_AMOUNT, ALICE); } - // TODO: Add test for sellAssetWithSig - // TODO: test for buyAsset failed issued asset amount? + function testSellAssetWithSig() public { + (gsmConverterSignerAddr, gsmConverterSignerKey) = makeAddrAndKey('randomString'); + + uint256 deadline = block.timestamp + 1 hours; + uint256 sellFee = GHO_GSM_FIXED_FEE_STRATEGY.getSellFee(DEFAULT_GSM_GHO_AMOUNT); + (uint256 expectedIssuedAssetAmount, uint256 expectedGhoBought, , ) = GHO_BUIDL_GSM + .getGhoAmountForSellAsset(DEFAULT_GSM_BUIDL_AMOUNT); + + vm.startPrank(FAUCET); + // Supply USDC to buyer + USDC_TOKEN.mint(gsmConverterSignerAddr, expectedIssuedAssetAmount); + // Supply BUIDL to issuance contract + BUIDL_TOKEN.mint(address(BUIDL_USDC_ISSUANCE), expectedIssuedAssetAmount); + vm.stopPrank(); + + vm.prank(gsmConverterSignerAddr); + USDC_TOKEN.approve(address(GSM_CONVERTER), expectedIssuedAssetAmount); + + assertEq( + GSM_CONVERTER.nonces(gsmConverterSignerAddr), + 0, + 'Unexpected before gsmConverterSignerAddr nonce' + ); + + bytes32 digest = keccak256( + abi.encode( + '\x19\x01', + GSM_CONVERTER.DOMAIN_SEPARATOR(), + GSM_CONVERTER_SELL_ASSET_WITH_SIG_TYPEHASH, + abi.encode( + gsmConverterSignerAddr, + DEFAULT_GSM_BUIDL_AMOUNT, + gsmConverterSignerAddr, + GSM_CONVERTER.nonces(gsmConverterSignerAddr), + deadline + ) + ) + ); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(gsmConverterSignerKey, digest); + bytes memory signature = abi.encodePacked(r, s, v); + + assertTrue(gsmConverterSignerAddr != ALICE, 'Signer is the same as Bob'); + + vm.prank(ALICE); + vm.expectEmit(true, true, true, true, address(GSM_CONVERTER)); + emit SellAssetThroughIssuance( + gsmConverterSignerAddr, + gsmConverterSignerAddr, + expectedIssuedAssetAmount, + expectedGhoBought + ); + (uint256 assetAmount, uint256 ghoBought) = GSM_CONVERTER.sellAssetWithSig( + gsmConverterSignerAddr, + DEFAULT_GSM_BUIDL_AMOUNT, + gsmConverterSignerAddr, + deadline, + signature + ); + vm.stopPrank(); + + // assertEq(ghoSold, expectedGhoSold, 'Unexpected GHO sold amount'); + // assertEq(redeemedUSDCAmount, DEFAULT_GSM_BUIDL_AMOUNT, 'Unexpected redeemed buyAsset amount'); + // assertEq( + // USDC_TOKEN.balanceOf(gsmConverterSignerAddr), + // DEFAULT_GSM_BUIDL_AMOUNT, + // 'Unexpected buyer final USDC balance' + // ); + // assertEq(USDC_TOKEN.balanceOf(address(GHO_BUIDL_GSM)), 0, 'Unexpected GSM final USDC balance'); + // assertEq( + // USDC_TOKEN.balanceOf(address(GSM_CONVERTER)), + // 0, + // 'Unexpected converter final USDC balance' + // ); + // assertEq( + // GHO_TOKEN.balanceOf(address(gsmConverterSignerAddr)), + // 0, + // 'Unexpected buyer final GHO balance' + // ); + // assertEq( + // GHO_TOKEN.balanceOf(address(GHO_BUIDL_GSM)), + // GHO_GSM_FIXED_FEE_STRATEGY.getSellFee(DEFAULT_GSM_GHO_AMOUNT) + buyFee, + // 'Unexpected GSM final GHO balance' + // ); + // assertEq( + // GHO_TOKEN.balanceOf(address(GSM_CONVERTER)), + // 0, + // 'Unexpected GSM_CONVERTER final GHO balance' + // ); + // assertEq( + // BUIDL_TOKEN.balanceOf(gsmConverterSignerAddr), + // 0, + // 'Unexpected buyer final BUIDL balance' + // ); + // assertEq( + // BUIDL_TOKEN.balanceOf(address(GHO_BUIDL_GSM)), + // 0, + // 'Unexpected GSM final BUIDL balance' + // ); + // assertEq( + // BUIDL_TOKEN.balanceOf(address(GSM_CONVERTER)), + // 0, + // 'Unexpected GSM_CONVERTER final BUIDL balance' + // ); + } + + // TODO: test for buyAsset, check assertions on every balance function testBuyAsset() public { uint256 sellFee = GHO_GSM_FIXED_FEE_STRATEGY.getSellFee(DEFAULT_GSM_GHO_AMOUNT); @@ -753,7 +857,7 @@ contract TestGsmConverter is TestGhoBase { abi.encode( '\x19\x01', GSM_CONVERTER.DOMAIN_SEPARATOR(), - GSM_BUY_ASSET_WITH_SIG_TYPEHASH, + GSM_CONVERTER_BUY_ASSET_WITH_SIG_TYPEHASH, abi.encode( gsmConverterSignerAddr, DEFAULT_GSM_BUIDL_AMOUNT, @@ -867,7 +971,7 @@ contract TestGsmConverter is TestGhoBase { abi.encode( '\x19\x01', GSM_CONVERTER.DOMAIN_SEPARATOR(), - GSM_BUY_ASSET_WITH_SIG_TYPEHASH, + GSM_CONVERTER_BUY_ASSET_WITH_SIG_TYPEHASH, abi.encode( gsmConverterSignerAddr, DEFAULT_GSM_BUIDL_AMOUNT, @@ -978,7 +1082,7 @@ contract TestGsmConverter is TestGhoBase { abi.encode( '\x19\x01', GSM_CONVERTER.DOMAIN_SEPARATOR(), - GSM_BUY_ASSET_WITH_SIG_TYPEHASH, + GSM_CONVERTER_BUY_ASSET_WITH_SIG_TYPEHASH, abi.encode( gsmConverterSignerAddr, minAssetAmount, @@ -1083,7 +1187,7 @@ contract TestGsmConverter is TestGhoBase { abi.encode( '\x19\x01', GSM_CONVERTER.DOMAIN_SEPARATOR(), - GSM_BUY_ASSET_WITH_SIG_TYPEHASH, + GSM_CONVERTER_BUY_ASSET_WITH_SIG_TYPEHASH, abi.encode( gsmConverterSignerAddr, DEFAULT_GSM_BUIDL_AMOUNT, @@ -1143,7 +1247,7 @@ contract TestGsmConverter is TestGhoBase { abi.encode( '\x19\x01', GSM_CONVERTER.DOMAIN_SEPARATOR(), - GSM_BUY_ASSET_WITH_SIG_TYPEHASH, + GSM_CONVERTER_BUY_ASSET_WITH_SIG_TYPEHASH, abi.encode( gsmConverterSignerAddr, DEFAULT_GSM_BUIDL_AMOUNT, @@ -1203,7 +1307,7 @@ contract TestGsmConverter is TestGhoBase { abi.encode( '\x19\x01', GSM_CONVERTER.DOMAIN_SEPARATOR(), - GSM_BUY_ASSET_WITH_SIG_TYPEHASH, + GSM_CONVERTER_BUY_ASSET_WITH_SIG_TYPEHASH, abi.encode( gsmConverterSignerAddr, DEFAULT_GSM_BUIDL_AMOUNT, diff --git a/src/test/helpers/Constants.sol b/src/test/helpers/Constants.sol index 98dd2770..a4f45ba1 100644 --- a/src/test/helpers/Constants.sol +++ b/src/test/helpers/Constants.sol @@ -36,6 +36,16 @@ contract Constants { 'SellAssetWithSig(address originator,uint256 maxAmount,address receiver,uint256 nonce,uint256 deadline)' ); + // signature typehash for GSM Converter + bytes32 public constant GSM_CONVERTER_BUY_ASSET_WITH_SIG_TYPEHASH = + keccak256( + 'BuyAssetWithSig(address originator,uint256 minAmount,address receiver,uint256 nonce,uint256 deadline)' + ); + bytes32 public constant GSM_CONVERTER_SELL_ASSET_WITH_SIG_TYPEHASH = + keccak256( + 'SellAssetWithSig(address originator,uint256 maxAmount,address receiver,uint256 nonce,uint256 deadline)' + ); + // defaults used in test environment uint256 constant DEFAULT_FLASH_FEE = 0.0009e4; // 0.09% uint128 constant DEFAULT_CAPACITY = 100_000_000e18;