github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/erc20/keeper/evm_log_handler_test.go (about) 1 package keeper_test 2 3 import ( 4 "errors" 5 "fmt" 6 "math/big" 7 "time" 8 9 "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/02-client/types" 10 connectiontypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/03-connection/types" 11 channeltypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/04-channel/types" 12 commitmenttypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/23-commitment/types" 13 host "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/24-host" 14 ibctmtypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/light-clients/07-tendermint/types" 15 ibctesting "github.com/fibonacci-chain/fbc/libs/ibc-go/testing" 16 17 "github.com/ethereum/go-ethereum/common" 18 sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types" 19 types2 "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/apps/transfer/types" 20 "github.com/fibonacci-chain/fbc/x/erc20/keeper" 21 ) 22 23 const CorrectIbcDenom2 = "ibc/3EF3B49764DB0E2284467F8BF7A08C18EACACB30E1AD7ABA8E892F1F679443F9" 24 const CorrectIbcDenom = "ibc/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" 25 26 func (suite *KeeperTestSuite) TestSendToIbcHandler() { 27 contract := common.BigToAddress(big.NewInt(1)) 28 sender := common.BigToAddress(big.NewInt(2)) 29 invalidDenom := "testdenom" 30 validDenom := CorrectIbcDenom 31 var data []byte 32 33 testCases := []struct { 34 msg string 35 malleate func() 36 postcheck func() 37 error error 38 }{ 39 { 40 "non associated coin denom, expect fail", 41 func() { 42 coin := sdk.NewCoin(invalidDenom, sdk.NewInt(100)) 43 err := suite.MintCoins(sdk.AccAddress(contract.Bytes()), sdk.NewCoins(coin)) 44 suite.Require().NoError(err) 45 46 balance := suite.GetBalance(sdk.AccAddress(contract.Bytes()), invalidDenom) 47 suite.Require().Equal(coin, balance) 48 49 input, err := keeper.SendToIbcEvent.Inputs.Pack( 50 sender, 51 "recipient", 52 coin.Amount.BigInt(), 53 ) 54 suite.Require().NoError(err) 55 data = input 56 }, 57 func() {}, 58 errors.New("contract 0x0000000000000000000000000000000000000001 is not connected to native token"), 59 }, 60 { 61 "non IBC denom, expect fail", 62 func() { 63 suite.app.Erc20Keeper.SetContractForDenom(suite.ctx, invalidDenom, contract) 64 coin := sdk.NewCoin(invalidDenom, sdk.NewInt(100)) 65 err := suite.MintCoins(sdk.AccAddress(contract.Bytes()), sdk.NewCoins(coin)) 66 suite.Require().NoError(err) 67 68 balance := suite.GetBalance(sdk.AccAddress(contract.Bytes()), invalidDenom) 69 suite.Require().Equal(coin, balance) 70 71 input, err := keeper.SendToIbcEvent.Inputs.Pack( 72 sender, 73 "recipient", 74 coin.Amount.BigInt(), 75 ) 76 suite.Require().NoError(err) 77 data = input 78 }, 79 func() {}, 80 errors.New("the native token associated with the contract 0x0000000000000000000000000000000000000001 is not an ibc voucher"), 81 }, 82 { 83 "success send to ibc", 84 func() { 85 amount := sdk.NewInt(100) 86 suite.app.TransferKeeper.SetParams(suite.ctx, types2.Params{ 87 true, true, 88 }) 89 channelA := "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" 90 suite.app.TransferKeeper.SetDenomTrace(suite.ctx, types2.DenomTrace{ 91 BaseDenom: "ibc/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", Path: "", 92 }) 93 suite.app.TransferKeeper.BindPort(suite.ctx, "transfer") 94 cap, _ := suite.app.ScopedTransferKeeper.NewCapability(suite.ctx, host.ChannelCapabilityPath("transfer", channelA)) 95 suite.app.ScopedIBCKeeper.ClaimCapability(suite.ctx, cap, host.ChannelCapabilityPath("transfer", channelA)) 96 suite.app.Erc20Keeper.SetContractForDenom(suite.ctx, CorrectIbcDenom2, contract) 97 c := channeltypes.Channel{ 98 State: channeltypes.OPEN, 99 Ordering: channeltypes.UNORDERED, 100 Counterparty: channeltypes.Counterparty{ 101 PortId: "transfer", 102 ChannelId: channelA, 103 }, 104 ConnectionHops: []string{"one"}, 105 Version: "version", 106 } 107 108 suite.app.IBCKeeper.V2Keeper.ChannelKeeper.SetNextSequenceSend(suite.ctx, "transfer", channelA, 1) 109 suite.app.IBCKeeper.V2Keeper.ChannelKeeper.SetChannel(suite.ctx, "transfer", channelA, c) 110 counterparty := connectiontypes.NewCounterparty("client-1", "one", commitmenttypes.NewMerklePrefix([]byte("ibc"))) 111 conn1 := connectiontypes.NewConnectionEnd(connectiontypes.OPEN, "client-1", counterparty, connectiontypes.ExportedVersionsToProto(connectiontypes.GetCompatibleVersions()), 0) 112 period := time.Hour * 24 * 7 * 2 113 clientState := ibctmtypes.NewClientState("testChainID", ibctmtypes.DefaultTrustLevel, period, period, period, types.NewHeight(0, 5), commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false) 114 suite.app.IBCKeeper.V2Keeper.ClientKeeper.SetClientState(suite.ctx, "client-1", clientState) 115 consensusState := ibctmtypes.NewConsensusState(time.Now(), commitmenttypes.NewMerkleRoot([]byte("root")), []byte("nextValsHash")) 116 suite.app.IBCKeeper.V2Keeper.ClientKeeper.SetClientConsensusState(suite.ctx, "client-1", types.NewHeight(0, 5), consensusState) 117 suite.app.IBCKeeper.V2Keeper.ConnectionKeeper.SetConnection(suite.ctx, "one", conn1) 118 coin := sdk.NewCoin(CorrectIbcDenom2, amount) 119 err := suite.MintCoins(sdk.AccAddress(contract.Bytes()), sdk.NewCoins(coin)) 120 suite.Require().NoError(err) 121 122 balance := suite.GetBalance(sdk.AccAddress(contract.Bytes()), CorrectIbcDenom2) 123 suite.Require().Equal(coin, balance) 124 125 input, err := keeper.SendToIbcEvent.Inputs.Pack( 126 sender, 127 "recipient", 128 coin.Amount.BigInt(), 129 ) 130 suite.Require().NoError(err) 131 data = input 132 }, 133 func() {}, 134 nil, 135 }, 136 { 137 "denomination trace not found", 138 func() { 139 amount := sdk.NewInt(100) 140 suite.app.Erc20Keeper.SetContractForDenom(suite.ctx, validDenom, contract) 141 coin := sdk.NewCoin(validDenom, amount) 142 err := suite.MintCoins(sdk.AccAddress(contract.Bytes()), sdk.NewCoins(coin)) 143 suite.Require().NoError(err) 144 145 balance := suite.GetBalance(sdk.AccAddress(contract.Bytes()), validDenom) 146 suite.Require().Equal(coin, balance) 147 148 input, err := keeper.SendToIbcEvent.Inputs.Pack( 149 sender, 150 "recipient", 151 coin.Amount.BigInt(), 152 ) 153 suite.Require().NoError(err) 154 data = input 155 }, 156 func() {}, 157 errors.New("denomination trace not found: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"), 158 }, 159 } 160 161 for _, tc := range testCases { 162 suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { 163 suite.SetupTest() 164 165 handler := keeper.NewSendToIbcEventHandler(suite.app.Erc20Keeper) 166 tc.malleate() 167 err := handler.Handle(suite.ctx, contract, data) 168 if tc.error != nil { 169 suite.Require().EqualError(err, tc.error.Error()) 170 } else { 171 suite.Require().NoError(err) 172 tc.postcheck() 173 } 174 }) 175 } 176 } 177 178 func (suite *KeeperTestSuite) TestSendNative20ToIbcHandler() { 179 contract := common.BigToAddress(big.NewInt(1)) 180 sender := common.BigToAddress(big.NewInt(2)) 181 validDenom := "testdenom" 182 183 var data []byte 184 185 testCases := []struct { 186 msg string 187 malleate func() 188 postcheck func() 189 error error 190 }{ 191 { 192 "non associated coin denom, expect fail", 193 func() { 194 coin := sdk.NewCoin(validDenom, sdk.NewInt(100)) 195 err := suite.MintCoins(sdk.AccAddress(contract.Bytes()), sdk.NewCoins(coin)) 196 suite.Require().NoError(err) 197 198 balance := suite.GetBalance(sdk.AccAddress(contract.Bytes()), validDenom) 199 suite.Require().Equal(coin, balance) 200 201 input, err := keeper.SendToIbcEvent.Inputs.Pack( 202 sender, 203 "recipient", 204 coin.Amount.BigInt(), 205 ) 206 suite.Require().NoError(err) 207 data = input 208 }, 209 func() {}, 210 errors.New("contract 0x0000000000000000000000000000000000000001 is not connected to native token"), 211 }, 212 { 213 "success send to ibc", 214 func() { 215 amount := sdk.NewInt(100) 216 suite.app.Erc20Keeper.SetContractForDenom(suite.ctx, validDenom, contract) 217 coin := sdk.NewCoin(validDenom, amount) 218 err := suite.MintCoins(sdk.AccAddress(contract.Bytes()), sdk.NewCoins(coin)) 219 suite.Require().NoError(err) 220 221 balance := suite.GetBalance(sdk.AccAddress(contract.Bytes()), validDenom) 222 suite.Require().Equal(coin, balance) 223 224 input, err := keeper.SendToIbcEvent.Inputs.Pack( 225 sender, 226 "recipient", 227 amount.BigInt(), 228 ) 229 suite.Require().NoError(err) 230 data = input 231 }, 232 func() {}, 233 nil, 234 }, 235 { 236 "portid channel error", 237 func() { 238 239 amount := sdk.NewInt(100) 240 suite.app.Erc20Keeper.SetContractForDenom(suite.ctx, validDenom, contract) 241 coin := sdk.NewCoin(validDenom, amount) 242 err := suite.MintCoins(sdk.AccAddress(contract.Bytes()), sdk.NewCoins(coin)) 243 suite.Require().NoError(err) 244 suite.ctx.SetIsCheckTx(false) 245 suite.ctx.SetIsTraceTx(false) 246 balance := suite.GetBalance(sdk.AccAddress(contract.Bytes()), validDenom) 247 suite.Require().Equal(coin, balance) 248 suite.app.TransferKeeper.SetParams(suite.ctx, types2.Params{true, true}) 249 input, err := keeper.SendNative20ToIbcEvent.Inputs.Pack( 250 sender, 251 "recipient", 252 coin.Amount.BigInt(), 253 "transfer", 254 "channel-0", 255 ) 256 suite.Require().NoError(err) 257 data = input 258 }, 259 func() {}, 260 errors.New("channel not found: port ID (transfer) channel ID (channel-0)"), 261 }, 262 } 263 264 for _, tc := range testCases { 265 suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { 266 suite.SetupTest() 267 268 handler := keeper.NewSendNative20ToIbcEventHandler(suite.app.Erc20Keeper) 269 tc.malleate() 270 err := handler.Handle(suite.ctx, contract, data) 271 if tc.error != nil { 272 suite.Require().EqualError(err, tc.error.Error()) 273 } else { 274 suite.Require().NoError(err) 275 tc.postcheck() 276 } 277 }) 278 } 279 }