Skip to content

Commit

Permalink
finalize withdraw
Browse files Browse the repository at this point in the history
  • Loading branch information
fbac committed Sep 17, 2024
1 parent 6a19fb0 commit e7ddcb0
Show file tree
Hide file tree
Showing 8 changed files with 291 additions and 36 deletions.
64 changes: 46 additions & 18 deletions e2e/e2etests/test_precompiles_bank.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package e2etests

import (
"fmt"
"math/big"

"github.com/ethereum/go-ethereum/accounts/abi/bind"
Expand All @@ -25,24 +24,21 @@ func TestPrecompilesBank(r *runner.E2ERunner, args []string) {

spender, bankAddr := r.EVMAddress(), bank.ContractAddress

// Create a bank contract caller.
bankContract, err := bank.NewIBank(bank.ContractAddress, r.ZEVMClient)
require.NoError(r, err, "Failed to create bank contract caller")

// Deposit and approve 50 WZETA for the test.
approveAmount := big.NewInt(0).Mul(big.NewInt(1e18), big.NewInt(50))
r.DepositAndApproveWZeta(approveAmount)
fmt.Printf("DEBUG: approveAmount %s\n", approveAmount.String())

// Initial WZETA spender balance should be 50.
initialBalance, err := r.WZeta.BalanceOf(&bind.CallOpts{Context: r.Ctx}, spender)
fmt.Printf("DEBUG: initialBalance %s\n", initialBalance.String())
require.NoError(r, err, "Error approving allowance for bank contract")
require.EqualValues(r, approveAmount, initialBalance, "spender balance should be 50")

// Create a bank contract caller.
bankContract, err := bank.NewIBank(bank.ContractAddress, r.ZEVMClient)
require.NoError(r, err, "Failed to create bank contract caller")

// Get the balance of the spender in coins "zevm/WZetaAddr". This calls bank.balanceOf().
// BalanceOf will convert the ZRC20 address to a Cosmos denom formatted as "zevm/0x12345".
// Initial cosmos coin spender balance should be 0.
retBalanceOf, err := bankContract.BalanceOf(&bind.CallOpts{Context: r.Ctx}, r.WZetaAddr, spender)
fmt.Printf("DEBUG: initial bank.balanceOf() %s\n", retBalanceOf.String())
require.NoError(r, err, "Error calling bank.balanceOf()")
require.EqualValues(r, uint64(0), retBalanceOf.Uint64(), "Initial cosmos coins balance has to be 0")

Expand All @@ -54,13 +50,11 @@ func TestPrecompilesBank(r *runner.E2ERunner, args []string) {

// Check the allowance of the bank in WZeta tokens. Should be 25.
balance, err := r.WZeta.Allowance(&bind.CallOpts{Context: r.Ctx}, spender, bankAddr)
fmt.Printf("DEBUG: bank allowance %s\n", balance.String())
require.NoError(r, err, "Error retrieving bank allowance")
require.EqualValues(r, uint64(25), balance.Uint64(), "Error allowance for bank contract")

// Call deposit with 25 coins.
// Call Deposit with 25 coins.
tx, err = bankContract.Deposit(r.ZEVMAuth, r.WZetaAddr, big.NewInt(25))
fmt.Printf("DEBUG: bank.deposit() tx hash %s\n", tx.Hash().String())
require.NoError(r, err, "Error calling bank.deposit()")
receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout)

Expand All @@ -70,22 +64,56 @@ func TestPrecompilesBank(r *runner.E2ERunner, args []string) {
require.Equal(r, big.NewInt(25).Uint64(), depositEvent.Amount.Uint64())
require.Equal(r, common.BytesToAddress(spender.Bytes()), depositEvent.Zrc20Depositor)
require.Equal(r, r.WZetaAddr, depositEvent.Zrc20Token)
fmt.Println("Deposit event emitted ", depositEvent)

// Check the balance of the spender in coins "zevm/WZetaAddr".
// After deposit, cosmos coin spender balance should be 25.
retBalanceOf, err = bankContract.BalanceOf(&bind.CallOpts{Context: r.Ctx}, r.WZetaAddr, spender)
fmt.Printf("DEBUG: final bank.balanceOf() tx %s\n", retBalanceOf.String())
require.NoError(r, err, "Error calling bank.balanceOf()")
require.EqualValues(r, uint64(25), retBalanceOf.Uint64(), "balanceOf result has to be 25")

// Check the balance of the spender in r.WZeta, should be 100 less.
// After deposit, WZeta spender balance should be 25 less than initial.
finalBalance, err := r.WZeta.BalanceOf(&bind.CallOpts{Context: r.Ctx}, spender)
fmt.Printf("DEBUG: final WZeta balance %s\n", finalBalance.String())
require.NoError(r, err, "Error retrieving final owner balance")
require.EqualValues(
r,
initialBalance.Uint64()-25, // expected
finalBalance.Uint64(), // actual
"Final balance should be initial - 25",
)

// After deposit, WZeta bank balance should be 25.
balance, err = r.WZeta.BalanceOf(&bind.CallOpts{Context: r.Ctx}, bankAddr)
require.NoError(r, err, "Error retrieving bank's balance")
require.EqualValues(r, uint64(25), balance.Uint64(), "Wrong locked WZeta amount in bank contract")

// Withdraw 15 coins to spender.
tx, err = bankContract.Withdraw(r.ZEVMAuth, r.WZetaAddr, big.NewInt(15))
require.NoError(r, err, "Error calling bank.withdraw()")
receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout)

// Withdraw event should be emitted.
withdrawEvent, err := bankContract.ParseWithdraw(*receipt.Logs[0])
require.NoError(r, err)
require.Equal(r, big.NewInt(15).Uint64(), withdrawEvent.Amount.Uint64())
require.Equal(r, common.BytesToAddress(spender.Bytes()), withdrawEvent.Zrc20Withdrawer)
require.Equal(r, r.WZetaAddr, withdrawEvent.Zrc20Token)

// After withdraw, WZeta spender balance should be only 10 less than initial. (25 - 15 = 10e2e/e2etests/test_precompiles_bank.go )
afterWithdraw, err := r.WZeta.BalanceOf(&bind.CallOpts{Context: r.Ctx}, spender)
require.NoError(r, err, "Error retrieving final owner balance")
require.EqualValues(
r,
initialBalance.Uint64()-10, // expected
afterWithdraw.Uint64(), // actual
"Balance after withdraw should be initial - 10",
)

// After withdraw, cosmos coin spender balance should be 10.
retBalanceOf, err = bankContract.BalanceOf(&bind.CallOpts{Context: r.Ctx}, r.WZetaAddr, spender)
require.NoError(r, err, "Error calling bank.balanceOf()")
require.EqualValues(r, uint64(10), retBalanceOf.Uint64(), "balanceOf result has to be 10")

// Final WZETA bank balance should be 10.
balance, err = r.WZeta.BalanceOf(&bind.CallOpts{Context: r.Ctx}, bankAddr)
require.NoError(r, err, "Error retrieving bank's allowance")
require.EqualValues(r, uint64(10), balance.Uint64(), "Wrong locked WZeta amount in bank contract")
}
12 changes: 12 additions & 0 deletions precompiles/bank/IBank.abi
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@
"name": "cosmos_token",
"type": "string"
},
{
"indexed": false,
"internalType": "string",
"name": "cosmos_address",
"type": "string"
},
{
"indexed": false,
"internalType": "uint256",
Expand Down Expand Up @@ -51,6 +57,12 @@
"name": "cosmos_token",
"type": "string"
},
{
"indexed": false,
"internalType": "string",
"name": "cosmos_address",
"type": "string"
},
{
"indexed": false,
"internalType": "uint256",
Expand Down
28 changes: 15 additions & 13 deletions precompiles/bank/IBank.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions precompiles/bank/IBank.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@
"name": "cosmos_token",
"type": "string"
},
{
"indexed": false,
"internalType": "string",
"name": "cosmos_address",
"type": "string"
},
{
"indexed": false,
"internalType": "uint256",
Expand Down Expand Up @@ -52,6 +58,12 @@
"name": "cosmos_token",
"type": "string"
},
{
"indexed": false,
"internalType": "string",
"name": "cosmos_address",
"type": "string"
},
{
"indexed": false,
"internalType": "uint256",
Expand Down
4 changes: 4 additions & 0 deletions precompiles/bank/IBank.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,27 @@ interface IBank {
/// @param zrc20_depositor Depositor EVM address.
/// @param zrc20_token ZRC20 address deposited.
/// @param cosmos_token Cosmos token denomination the tokens were converted into.
/// @param cosmos_address Cosmos address the tokens were deposited to.
/// @param amount Amount deposited.
event Deposit(
address indexed zrc20_depositor,
address indexed zrc20_token,
string indexed cosmos_token,
string cosmos_address,
uint256 amount
);

/// @notice Withdraw event is emitted when withdraw function is called.
/// @param zrc20_withdrawer Withdrawer EVM address.
/// @param zrc20_token ZRC20 address withdrawn.
/// @param cosmos_token Cosmos token denomination the tokens were converted from.
/// @param cosmos_address Cosmos address the tokens were withdrawn from.
/// @param amount Amount withdrawn.
event Withdraw(
address indexed zrc20_withdrawer,
address indexed zrc20_token,
string indexed cosmos_token,
string cosmos_address,
uint256 amount
);

Expand Down
49 changes: 45 additions & 4 deletions precompiles/bank/logs.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"math/big"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/vm"

Expand All @@ -20,6 +21,7 @@ func (c *Contract) AddDepositLog(
stateDB vm.StateDB,
zrc20Depositor common.Address,
zrc20Token common.Address,
cosmosAddr string,
cosmosCoin string,
amount *big.Int,
) error {
Expand All @@ -36,8 +38,27 @@ func (c *Contract) AddDepositLog(
return err
}

// amount is part of event data.
data, err := logs.PackBigInt(amount)
// Amount and cosmos address are part of event data.
uint256Type, err := abi.NewType("uint256", "", nil)
if err != nil {
return err
}

stringType, err := abi.NewType("string", "", nil)
if err != nil {
return err
}

arguments := abi.Arguments{
{
Type: stringType,
},
{
Type: uint256Type,
},
}

data, err := arguments.Pack(cosmosAddr, amount)
if err != nil {
return err
}
Expand All @@ -52,6 +73,7 @@ func (c *Contract) AddWithdrawLog(
stateDB vm.StateDB,
zrc20Withdrawer common.Address,
zrc20Token common.Address,
cosmosAddr string,
cosmosCoin string,
amount *big.Int,
) error {
Expand All @@ -68,8 +90,27 @@ func (c *Contract) AddWithdrawLog(
return err
}

// amount is part of event data.
data, err := logs.PackBigInt(amount)
// Amount and cosmos address are part of event data.
uint256Type, err := abi.NewType("uint256", "", nil)
if err != nil {
return err
}

stringType, err := abi.NewType("string", "", nil)
if err != nil {
return err
}

arguments := abi.Arguments{
{
Type: stringType,
},
{
Type: uint256Type,
},
}

data, err := arguments.Pack(cosmosAddr, amount)
if err != nil {
return err
}
Expand Down
Loading

0 comments on commit e7ddcb0

Please sign in to comment.