diff --git a/clients/balanceValidator/balanceValidator.go b/clients/balanceValidator/balanceValidator.go index 1f6a7a65..c3a3c844 100644 --- a/clients/balanceValidator/balanceValidator.go +++ b/clients/balanceValidator/balanceValidator.go @@ -111,6 +111,8 @@ func (validator *balanceValidator) CheckToken(ctx context.Context, ethToken comm "amount", amount.String(), ) + // TODO(next PRs): fix here to not consider the pending batch in the mvx->eth direction that executed on eth. + if ethAmount.Cmp(mvxAmount) != 0 { return fmt.Errorf("%w, balance for ERC20 token %s is %s and the balance for ESDT token %s is %s, direction %s", ErrBalanceMismatch, ethToken.String(), ethAmount.String(), mvxToken, mvxAmount.String(), direction) diff --git a/clients/ethereum/contract/GenericERC20.go b/clients/ethereum/contract/GenericERC20.go index 9ade7165..c03630ae 100644 --- a/clients/ethereum/contract/GenericERC20.go +++ b/clients/ethereum/contract/GenericERC20.go @@ -31,7 +31,7 @@ var ( // GenericERC20MetaData contains all meta data concerning the GenericERC20 contract. var GenericERC20MetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"tokenName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"tokenSymbol\",\"type\":\"string\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"allowance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"needed\",\"type\":\"uint256\"}],\"name\":\"ERC20InsufficientAllowance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"needed\",\"type\":\"uint256\"}],\"name\":\"ERC20InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"approver\",\"type\":\"address\"}],\"name\":\"ERC20InvalidApprover\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"ERC20InvalidReceiver\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"ERC20InvalidSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"ERC20InvalidSpender\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipientAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + ABI: "[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"tokenName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"tokenSymbol\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"providedNumDecimals\",\"type\":\"uint8\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"allowance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"needed\",\"type\":\"uint256\"}],\"name\":\"ERC20InsufficientAllowance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"needed\",\"type\":\"uint256\"}],\"name\":\"ERC20InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"approver\",\"type\":\"address\"}],\"name\":\"ERC20InvalidApprover\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"ERC20InvalidReceiver\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"ERC20InvalidSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"ERC20InvalidSpender\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipientAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", } // GenericERC20ABI is the input ABI used to generate the binding from. diff --git a/clients/ethereum/contract/MintBurnERC20.go b/clients/ethereum/contract/MintBurnERC20.go index 29a319ae..66e58327 100644 --- a/clients/ethereum/contract/MintBurnERC20.go +++ b/clients/ethereum/contract/MintBurnERC20.go @@ -31,7 +31,7 @@ var ( // MintBurnERC20MetaData contains all meta data concerning the MintBurnERC20 contract. var MintBurnERC20MetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AccessControlBadConfirmation\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"neededRole\",\"type\":\"bytes32\"}],\"name\":\"AccessControlUnauthorizedAccount\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerNotMinter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"allowance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"needed\",\"type\":\"uint256\"}],\"name\":\"ERC20InsufficientAllowance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"needed\",\"type\":\"uint256\"}],\"name\":\"ERC20InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"approver\",\"type\":\"address\"}],\"name\":\"ERC20InvalidApprover\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"ERC20InvalidReceiver\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"ERC20InvalidSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"ERC20InvalidSpender\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"previousAdminRole\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"newAdminRole\",\"type\":\"bytes32\"}],\"name\":\"RoleAdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RoleGranted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RoleRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"DEFAULT_ADMIN_ROLE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MINTER_ROLE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"burnFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"}],\"name\":\"getRoleAdmin\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"grantRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"hasRole\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"callerConfirmation\",\"type\":\"address\"}],\"name\":\"renounceRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"revokeRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + ABI: "[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"providedNumDecimals\",\"type\":\"uint8\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AccessControlBadConfirmation\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"neededRole\",\"type\":\"bytes32\"}],\"name\":\"AccessControlUnauthorizedAccount\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"CallerNotMinter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"allowance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"needed\",\"type\":\"uint256\"}],\"name\":\"ERC20InsufficientAllowance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"needed\",\"type\":\"uint256\"}],\"name\":\"ERC20InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"approver\",\"type\":\"address\"}],\"name\":\"ERC20InvalidApprover\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"ERC20InvalidReceiver\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"ERC20InvalidSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"ERC20InvalidSpender\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"previousAdminRole\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"newAdminRole\",\"type\":\"bytes32\"}],\"name\":\"RoleAdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RoleGranted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RoleRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"DEFAULT_ADMIN_ROLE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MINTER_ROLE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"burnFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"}],\"name\":\"getRoleAdmin\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"grantRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"hasRole\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"callerConfirmation\",\"type\":\"address\"}],\"name\":\"renounceRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"revokeRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", } // MintBurnERC20ABI is the input ABI used to generate the binding from. diff --git a/integrationTests/relayers/slowTests/ethToMultiversXWithChainSimulator_test.go b/integrationTests/relayers/slowTests/ethToMultiversXWithChainSimulator_test.go index 46f8b860..57abf8db 100644 --- a/integrationTests/relayers/slowTests/ethToMultiversXWithChainSimulator_test.go +++ b/integrationTests/relayers/slowTests/ethToMultiversXWithChainSimulator_test.go @@ -12,7 +12,6 @@ import ( "testing" "time" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -21,9 +20,10 @@ const ( ) func TestRelayersShouldExecuteTransfers(t *testing.T) { - t.Run("ETH->MVX and back, ethNative = true, ethMintBurn = false, mvxNative = false, mvxMintBurn = true", func(t *testing.T) { - token1 := issueTokenParams{ - abstractTokenIdentifier: "ETHUSDC", + // USDC is ethNative = true, ethMintBurn = false, mvxNative = false, mvxMintBurn = true + usdcToken := testTokenParams{ + issueTokenParams: issueTokenParams{ + abstractTokenIdentifier: "USDC", numOfDecimalsUniversal: 6, numOfDecimalsChainSpecific: 6, mvxUniversalTokenTicker: "USDC", @@ -38,66 +38,137 @@ func TestRelayersShouldExecuteTransfers(t *testing.T) { valueToMintOnEth: "10000000000", isMintBurnOnEth: false, isNativeOnEth: true, - } - - valueToTransferToMvx := big.NewInt(5000) - // todo: refactor this - valueToSendFromMvX := big.NewInt(0).Div(valueToTransferToMvx, big.NewInt(2)) - var expectedFinalValueOnEth *big.Int - var expectedFinalValueOnMvXSafe *big.Int - setupFunc := func(tb testing.TB, testSetup *simulatedSetup) { - testSetup.issueAndConfigureTokens(token1) - - balance := testSetup.getESDTUniversalTokenBalance(testSetup.mvxReceiverAddress, token1.abstractTokenIdentifier) - assert.Equal(tb, big.NewInt(0).String(), balance.String()) + }, + testOperations: []tokenOperations{ + { + valueToTransferToMvx: big.NewInt(5000), + valueToSendFromMvX: big.NewInt(2500), + ethSCCallMethod: "", + ethSCCallGasLimit: 0, + ethSCCallArguments: nil, + }, + { + valueToTransferToMvx: big.NewInt(7000), + valueToSendFromMvX: big.NewInt(300), + ethSCCallMethod: "", + ethSCCallGasLimit: 0, + ethSCCallArguments: nil, + }, + { + valueToTransferToMvx: big.NewInt(1000), + valueToSendFromMvX: nil, + ethSCCallMethod: "callPayable", + ethSCCallGasLimit: 50000000, + ethSCCallArguments: nil, + }, + }, + esdtSafeExtraBalance: big.NewInt(100), // extra is just for the fees for the 2 transfers mvx->eth + ethTestAddrExtraBalance: big.NewInt(-5000 + 2500 - 50 - 7000 + 300 - 50 - 1000), // -(eth->mvx) + (mvx->eth) - fees + } - testSetup.createBatchOnEthereum(token1.abstractTokenIdentifier, valueToTransferToMvx, "", 0) + //MEME is ethNative = false, ethMintBurn = true, mvxNative = true, mvxMintBurn = false + memeToken := testTokenParams{ + issueTokenParams: issueTokenParams{ + abstractTokenIdentifier: "MEME", + numOfDecimalsUniversal: 1, + numOfDecimalsChainSpecific: 1, + mvxUniversalTokenTicker: "MEME", + mvxChainSpecificTokenTicker: "ETHMEME", + mvxUniversalTokenDisplayName: "WrappedMEME", + mvxChainSpecificTokenDisplayName: "EthereumWrappedMEME", + valueToMintOnMvx: "10000000000", + isMintBurnOnMvX: false, + isNativeOnMvX: true, + ethTokenName: "ETHMEME", + ethTokenSymbol: "ETHM", + valueToMintOnEth: "10000000000", + isMintBurnOnEth: true, + isNativeOnEth: false, + }, + testOperations: []tokenOperations{ + { + valueToTransferToMvx: big.NewInt(2400), + valueToSendFromMvX: big.NewInt(4000), + ethSCCallMethod: "", + ethSCCallGasLimit: 0, + ethSCCallArguments: nil, + }, + { + valueToTransferToMvx: big.NewInt(200), + valueToSendFromMvX: big.NewInt(6000), + ethSCCallMethod: "", + ethSCCallGasLimit: 0, + ethSCCallArguments: nil, + }, + { + valueToTransferToMvx: big.NewInt(1000), + valueToSendFromMvX: big.NewInt(2000), + ethSCCallMethod: "callPayable", + ethSCCallGasLimit: 50000000, + ethSCCallArguments: nil, + }, + }, + esdtSafeExtraBalance: big.NewInt(4000 + 6000 + 2000), // everything is locked in the safe esdt contract + ethTestAddrExtraBalance: big.NewInt(4000 - 50 + 6000 - 50 + 2000 - 50), + } - initialSafeValue := testSetup.getESDTChainSpecificTokenBalance(testSetup.mvxSafeAddress, token1.abstractTokenIdentifier) - expectedFinalValueOnMvXSafe = big.NewInt(0).Add(initialSafeValue, feeInt) - expectedFinalValueOnEth = big.NewInt(0).Sub(valueToSendFromMvX, feeInt) - } + testRelayersWithChainSimulatorAndTokens(t, usdcToken, memeToken) +} - ethToMVXDone := false - mvxToETHDone := false - processFunc := func(tb testing.TB, testSetup *simulatedSetup) bool { - receiverToCheckBalance := testSetup.mvxReceiverAddress - balance := testSetup.getESDTUniversalTokenBalance(receiverToCheckBalance, token1.abstractTokenIdentifier) - isTransferDoneFromETH := balance.String() == valueToTransferToMvx.String() - if !ethToMVXDone && isTransferDoneFromETH { - ethToMVXDone = true - log.Info("ETH->MvX transfer finished, now sending back to ETH...") +func testRelayersWithChainSimulatorAndTokens(tb testing.TB, tokens ...testTokenParams) { + startsFromEthFlow := &startsFromEthereumFlow{ + TB: tb, + tokens: make([]testTokenParams, 0, len(tokens)), + } - testSetup.sendMVXToEthTransaction(token1.abstractTokenIdentifier, valueToSendFromMvX) - } + startsFromMvXFlow := &startsFromMultiversXFlow{ + TB: tb, + tokens: make([]testTokenParams, 0, len(tokens)), + } - ethOwnerBalance := testSetup.getEthBalance(testSetup.ethOwnerAddress, token1.abstractTokenIdentifier) - isTransferDoneFromMVX := ethOwnerBalance.String() == expectedFinalValueOnEth.String() + // split the tokens from where should the bridge start + for _, token := range tokens { + if token.isNativeOnEth { + startsFromEthFlow.tokens = append(startsFromEthFlow.tokens, token) + continue + } + if token.isNativeOnMvX { + startsFromMvXFlow.tokens = append(startsFromMvXFlow.tokens, token) + continue + } + require.Fail(tb, "invalid setup, found a token that is not native on any chain", "abstract identifier", token.abstractTokenIdentifier) + } - balance = testSetup.getESDTChainSpecificTokenBalance(testSetup.mvxSafeAddress, token1.abstractTokenIdentifier) - safeSavedFee := expectedFinalValueOnMvXSafe.String() == balance.String() + setupFunc := func(tb testing.TB, testSetup *simulatedSetup) { + startsFromMvXFlow.testSetup = testSetup + startsFromEthFlow.testSetup = testSetup - if !mvxToETHDone && isTransferDoneFromMVX && safeSavedFee { - mvxToETHDone = true - } + testSetup.issueAndConfigureTokens(tokens...) + testSetup.checkForZeroBalanceOnReceivers(tokens...) + if len(startsFromEthFlow.tokens) > 0 { + testSetup.createBatchOnEthereum(startsFromEthFlow.tokens...) + } + if len(startsFromMvXFlow.tokens) > 0 { + testSetup.createBatchOnMultiversX(startsFromMvXFlow.tokens...) + } + } - if ethToMVXDone && mvxToETHDone { - log.Info("MvX<->ETH transfers done") - return true - } + processFunc := func(tb testing.TB, testSetup *simulatedSetup) bool { + if startsFromEthFlow.process() && startsFromMvXFlow.process() { + return true + } - // commit blocks in order to execute incoming txs from relayers - testSetup.simulatedETHChain.Commit() - testSetup.mvxChainSimulator.GenerateBlocks(testSetup.testContext, 1) + // commit blocks in order to execute incoming txs from relayers + testSetup.simulatedETHChain.Commit() + testSetup.mvxChainSimulator.GenerateBlocks(testSetup.testContext, 1) - return false - } + return false + } - testRelayersWithChainSimulator(t, - setupFunc, - processFunc, - ) - }) + testRelayersWithChainSimulator(tb, + setupFunc, + processFunc, + ) } func testRelayersWithChainSimulator(tb testing.TB, @@ -107,7 +178,7 @@ func testRelayersWithChainSimulator(tb testing.TB, defer func() { r := recover() if r != nil { - require.Fail(tb, "should have not panicked") + require.Fail(tb, fmt.Sprintf("should have not panicked: %v", r)) } }() diff --git a/integrationTests/relayers/slowTests/interface.go b/integrationTests/relayers/slowTests/interface.go index ad61160e..fa72e3fe 100644 --- a/integrationTests/relayers/slowTests/interface.go +++ b/integrationTests/relayers/slowTests/interface.go @@ -7,6 +7,7 @@ import ( "math/big" goEthereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/multiversx/mx-bridge-eth-go/clients/multiversx" @@ -42,3 +43,9 @@ type bridgeComponents interface { Start() error Close() error } + +type erc20Contract interface { + BalanceOf(opts *bind.CallOpts, account common.Address) (*big.Int, error) + Mint(opts *bind.TransactOpts, recipientAddress common.Address, amount *big.Int) (*types.Transaction, error) + Approve(opts *bind.TransactOpts, spender common.Address, value *big.Int) (*types.Transaction, error) +} diff --git a/integrationTests/relayers/slowTests/simulatedSetup.go b/integrationTests/relayers/slowTests/simulatedSetup.go index 09c854dc..37e95645 100644 --- a/integrationTests/relayers/slowTests/simulatedSetup.go +++ b/integrationTests/relayers/slowTests/simulatedSetup.go @@ -10,11 +10,11 @@ import ( "encoding/pem" "fmt" "io" - "math" "math/big" "os" "path" "strings" + "sync" "testing" "time" @@ -23,6 +23,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" "github.com/ethereum/go-ethereum/common" ethCore "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/multiversx/mx-bridge-eth-go/clients/ethereum" "github.com/multiversx/mx-bridge-eth-go/clients/ethereum/contract" @@ -107,17 +108,20 @@ const ( // Ethereum related consts ethSimulatedGasLimit = 9000000 - erc20SafeABI = "testdata/contracts/eth/ERC20Safe.json" + erc20SafeABI = "testdata/contracts/eth/ERC20Safe.abi.json" erc20SafeBytecode = "testdata/contracts/eth/ERC20Safe.hex" - bridgeABI = "testdata/contracts/eth/Bridge.json" + bridgeABI = "testdata/contracts/eth/Bridge.abi.json" bridgeBytecode = "testdata/contracts/eth/Bridge.hex" - scExecProxyABI = "testdata/contracts/eth/SCExecProxy.json" + scExecProxyABI = "testdata/contracts/eth/SCExecProxy.abi.json" scExecProxyBytecode = "testdata/contracts/eth/SCExecProxy.hex" - genericERC20ABI = "testdata/contracts/eth/GenericERC20.json" + genericERC20ABI = "testdata/contracts/eth/GenericERC20.abi.json" genericERC20Bytecode = "testdata/contracts/eth/GenericERC20.hex" + mintBurnERC20ABI = "testdata/contracts/eth/MintBurnERC20.abi.json" + mintBurnERC20Bytecode = "testdata/contracts/eth/MintBurnERC20.hex" ethMinAmountAllowedToTransfer = 25 ethMaxAmountAllowedToTransfer = 500000 ethStatusSuccess = uint64(1) + minterRoleString = "MINTER_ROLE" ) var ( @@ -125,7 +129,9 @@ var ( log = logger.GetOrCreate("integrationTests/relayers/slowTests") ethOwnerSK, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") ethDepositorSK, _ = crypto.HexToECDSA("9bb971db41e3815a669a71c3f1bcb24e0b81f21e04bf11faa7a34b9b40e7cfb1") + ethTestAddress, _ = crypto.HexToECDSA("dafea2c94bfe5d25f1a508808c2bc2c2e6c6f18b6b010fc841d8eb80755ba27a") feeInt, _ = big.NewInt(0).SetString(fee, 10) + zeroValueBigInt = big.NewInt(0) ) type keysHolder struct { @@ -158,6 +164,7 @@ type simulatedSetup struct { mvxOwnerKeys keysHolder ethOwnerAddress common.Address ethDepositorAddr common.Address + ethTestAddr common.Address ethChainID *big.Int ethSafeAddress common.Address ethSafeContract *contract.ERC20Safe @@ -169,6 +176,9 @@ type simulatedSetup struct { scCallerModule io.Closer erc20ContractsHolder ethereum.Erc20ContractsHolder ethChainWrapper ethereum.ClientWrapper + mutBalances sync.RWMutex + esdtBalanceForSafe map[string]*big.Int + ethBalanceTestAddress map[string]*big.Int } type issueTokenParams struct { @@ -176,7 +186,7 @@ type issueTokenParams struct { // MultiversX numOfDecimalsUniversal int - numOfDecimalsChainSpecific int + numOfDecimalsChainSpecific byte mvxUniversalTokenTicker string mvxChainSpecificTokenTicker string mvxUniversalTokenDisplayName string @@ -193,16 +203,34 @@ type issueTokenParams struct { isNativeOnEth bool } +type tokenOperations struct { + valueToTransferToMvx *big.Int + valueToSendFromMvX *big.Int + ethSCCallMethod string + ethSCCallGasLimit uint64 + ethSCCallArguments []string +} + +type testTokenParams struct { + issueTokenParams + testOperations []tokenOperations + esdtSafeExtraBalance *big.Int + ethTestAddrExtraBalance *big.Int +} + func prepareSimulatedSetup(tb testing.TB) *simulatedSetup { log.Info(fmt.Sprintf(logStepMarker, "starting setup")) var err error testSetup := &simulatedSetup{ - TB: tb, - tokensRegistry: newTokenRegistry(tb), - workingDir: tb.TempDir(), - ethOwnerAddress: crypto.PubkeyToAddress(ethOwnerSK.PublicKey), - ethDepositorAddr: crypto.PubkeyToAddress(ethDepositorSK.PublicKey), + TB: tb, + tokensRegistry: newTokenRegistry(tb), + workingDir: tb.TempDir(), + ethOwnerAddress: crypto.PubkeyToAddress(ethOwnerSK.PublicKey), + ethDepositorAddr: crypto.PubkeyToAddress(ethDepositorSK.PublicKey), + ethTestAddr: crypto.PubkeyToAddress(ethTestAddress.PublicKey), + esdtBalanceForSafe: make(map[string]*big.Int), + ethBalanceTestAddress: make(map[string]*big.Int), } // create a test context @@ -244,7 +272,7 @@ func prepareSimulatedSetup(tb testing.TB) *simulatedSetup { return testSetup } -func (testSetup *simulatedSetup) issueAndConfigureTokens(tokens ...issueTokenParams) { +func (testSetup *simulatedSetup) issueAndConfigureTokens(tokens ...testTokenParams) { log.Info(fmt.Sprintf(logStepMarker, fmt.Sprintf("issuing %d tokens", len(tokens)))) require.Greater(testSetup, len(tokens), 0) @@ -253,22 +281,64 @@ func (testSetup *simulatedSetup) issueAndConfigureTokens(tokens ...issueTokenPar testSetup.pauseMvxContractsForTokenChanges() for _, token := range tokens { - testSetup.addToken(token) - testSetup.issueAndWhitelistTokenOnEth(token) - testSetup.issueAndWhitelistTokenOnMvx(token) + testSetup.addToken(token.issueTokenParams) + testSetup.issueAndWhitelistTokenOnEth(token.issueTokenParams) + testSetup.issueAndWhitelistTokenOnMvx(token.issueTokenParams) } testSetup.unPauseEthContractsForTokenChanges() testSetup.unPauseMvxContractsForTokenChanges() - timestamp, err := testSetup.mvxChainSimulator.GetBlockchainTimeStamp(testSetup.testContext) - require.Nil(testSetup, err) - require.Greater(testSetup, timestamp, uint64(0), "something went wrong and the chain simulator returned 0 for the current timestamp") - - timestampAsBigInt := big.NewInt(0).SetUint64(timestamp) for _, token := range tokens { - testSetup.submitAggregatorBatch(token, timestampAsBigInt) + testSetup.submitAggregatorBatch(token.issueTokenParams) + } +} + +func (testSetup *simulatedSetup) checkForZeroBalanceOnReceivers(tokens ...testTokenParams) { + for _, params := range tokens { + testSetup.checkForZeroBalanceOnReceiversForToken(params) + } +} + +func (testSetup *simulatedSetup) checkForZeroBalanceOnReceiversForToken(token testTokenParams) { + balance := testSetup.getESDTUniversalTokenBalance(testSetup.mvxReceiverAddress, token.abstractTokenIdentifier) + require.Equal(testSetup, big.NewInt(0).String(), balance.String()) + + balance = testSetup.getESDTUniversalTokenBalance(testSetup.mvxTestCallerAddress, token.abstractTokenIdentifier) + require.Equal(testSetup, big.NewInt(0).String(), balance.String()) +} + +func (testSetup *simulatedSetup) isTransferDoneFromEthereum(tokens ...testTokenParams) bool { + isDone := true + for _, params := range tokens { + isDone = isDone && testSetup.isTransferDoneFromEthereumForToken(params) + } + + return isDone +} + +func (testSetup *simulatedSetup) isTransferDoneFromEthereumForToken(params testTokenParams) bool { + expectedValueOnReceiver := big.NewInt(0) + expectedValueOnContract := big.NewInt(0) + for _, operation := range params.testOperations { + if operation.valueToTransferToMvx == nil { + continue + } + + if len(operation.ethSCCallMethod) > 0 { + expectedValueOnContract.Add(expectedValueOnContract, operation.valueToTransferToMvx) + } else { + expectedValueOnReceiver.Add(expectedValueOnReceiver, operation.valueToTransferToMvx) + } + } + + receiverBalance := testSetup.getESDTUniversalTokenBalance(testSetup.mvxReceiverAddress, params.abstractTokenIdentifier) + if receiverBalance.String() != expectedValueOnReceiver.String() { + return false } + + contractBalance := testSetup.getESDTUniversalTokenBalance(testSetup.mvxTestCallerAddress, params.abstractTokenIdentifier) + return contractBalance.String() == expectedValueOnContract.String() } func (testSetup *simulatedSetup) startRelayersAndScModule() { @@ -898,7 +968,7 @@ func (testSetup *simulatedSetup) issueAndWhitelistTokenOnMvx(params issueTokenPa zeroValue, addMapping, []string{ - hex.EncodeToString(token.ethGenericTokenAddress.Bytes()), + hex.EncodeToString(token.ethErc20Address.Bytes()), hex.EncodeToString([]byte(mvxChainSpecificToken))}) require.NoError(testSetup, err) txResult, err = testSetup.mvxChainSimulator.GetTransactionResult(testSetup.testContext, hash) @@ -977,6 +1047,16 @@ func (testSetup *simulatedSetup) issueAndWhitelistTokenOnMvx(params issueTokenPa require.NoError(testSetup, err) log.Info("multi-transfer set max bridge amount for token tx executed", "hash", hash, "status", txResult.Status) + + esdtBalanceForSafe := testSetup.getESDTChainSpecificTokenBalance(testSetup.mvxSafeAddress, params.abstractTokenIdentifier) + ethBalanceForTestAddr := testSetup.getEthBalance(testSetup.ethTestAddr, params.abstractTokenIdentifier) + testSetup.mutBalances.Lock() + testSetup.esdtBalanceForSafe[params.abstractTokenIdentifier] = esdtBalanceForSafe + testSetup.ethBalanceTestAddress[params.abstractTokenIdentifier] = ethBalanceForTestAddr + testSetup.mutBalances.Unlock() + + log.Info("recorded the ESDT balance for safe contract", "token", params.abstractTokenIdentifier, "balance", esdtBalanceForSafe.String()) + log.Info("recorded the ETH balance for test address", "token", params.abstractTokenIdentifier, "balance", ethBalanceForTestAddr.String()) } func (testSetup *simulatedSetup) unPauseMvxContractsForTokenChanges() { @@ -1118,18 +1198,66 @@ func (testSetup *simulatedSetup) getESDTChainSpecificTokenBalance( func (testSetup *simulatedSetup) getEthBalance(receiver common.Address, abstractTokenIdentifier string) *big.Int { token := testSetup.getTokenData(abstractTokenIdentifier) require.NotNil(testSetup, token) - require.NotNil(testSetup, token.ethGenericTokenContract) + require.NotNil(testSetup, token.ethErc20Address) - balance, err := token.ethGenericTokenContract.BalanceOf(nil, receiver) + balance, err := token.ethErc20Contract.BalanceOf(nil, receiver) require.NoError(testSetup, err) return balance } -func (testSetup *simulatedSetup) sendMVXToEthTransaction(abstractTokenIdentifier string, value *big.Int) string { - token := testSetup.getTokenData(abstractTokenIdentifier) +func (testSetup *simulatedSetup) sendFromMultiversxToEthereum(tokensParams ...testTokenParams) { + for _, params := range tokensParams { + testSetup.sendFromMultiversxToEthereumForToken(params) + } +} + +func (testSetup *simulatedSetup) sendFromMultiversxToEthereumForToken(params testTokenParams) { + token := testSetup.getTokenData(params.abstractTokenIdentifier) require.NotNil(testSetup, token) + for _, operation := range params.testOperations { + if operation.valueToSendFromMvX == nil { + continue + } + + testSetup.sendDepositTransactionFromMultiversx(token, operation.valueToSendFromMvX) + } +} + +func (testSetup *simulatedSetup) sendFromEthereumToMultiversX(tokensParams ...testTokenParams) { + for _, params := range tokensParams { + testSetup.createDepositsOnEthereumForToken(params, ethTestAddress) + } +} + +func (testSetup *simulatedSetup) isTransferDoneFromMultiversX(tokens ...testTokenParams) bool { + isDone := true + for _, params := range tokens { + isDone = isDone && testSetup.isTransferDoneFromMultiversXForToken(params) + } + + return isDone +} + +func (testSetup *simulatedSetup) isTransferDoneFromMultiversXForToken(params testTokenParams) bool { + testSetup.mutBalances.Lock() + initialBalanceForSafe := testSetup.esdtBalanceForSafe[params.abstractTokenIdentifier] + expectedReceiver := big.NewInt(0).Set(testSetup.ethBalanceTestAddress[params.abstractTokenIdentifier]) + expectedReceiver.Add(expectedReceiver, params.ethTestAddrExtraBalance) + testSetup.mutBalances.Unlock() + + ethTestBalance := testSetup.getEthBalance(testSetup.ethTestAddr, params.abstractTokenIdentifier) + isTransferDoneFromMultiversX := ethTestBalance.String() == expectedReceiver.String() + + expectedEsdtSafe := big.NewInt(0).Add(initialBalanceForSafe, params.esdtSafeExtraBalance) + balanceForSafe := testSetup.getESDTChainSpecificTokenBalance(testSetup.mvxSafeAddress, params.abstractTokenIdentifier) + isSafeContractOnCorrectBalance := expectedEsdtSafe.String() == balanceForSafe.String() + + return isTransferDoneFromMultiversX && isSafeContractOnCorrectBalance +} + +func (testSetup *simulatedSetup) sendDepositTransactionFromMultiversx(token *tokenData, value *big.Int) { // unwrap token paramsUnwrap := []string{ hex.EncodeToString([]byte(token.mvxUniversalToken)), @@ -1150,7 +1278,7 @@ func (testSetup *simulatedSetup) sendMVXToEthTransaction(abstractTokenIdentifier hex.EncodeToString([]byte(token.mvxChainSpecificToken)), hex.EncodeToString(value.Bytes()), hex.EncodeToString([]byte(createTransactionParam)), - hex.EncodeToString(testSetup.ethOwnerAddress.Bytes()), + hex.EncodeToString(testSetup.ethTestAddr.Bytes()), } hash, err = testSetup.mvxChainSimulator.ScCall( @@ -1166,12 +1294,16 @@ func (testSetup *simulatedSetup) sendMVXToEthTransaction(abstractTokenIdentifier txResult, err = testSetup.mvxChainSimulator.GetTransactionResult(testSetup.testContext, hash) require.NoError(testSetup, err) - log.Info("MVX->ETH transaction sent", "hash", hash, "status", txResult.Status) - - return hash + log.Info("MultiversX->Ethereum transaction sent", "hash", hash, "status", txResult.Status) } -func (testSetup *simulatedSetup) submitAggregatorBatch(params issueTokenParams, timestampAsBigInt *big.Int) { +func (testSetup *simulatedSetup) submitAggregatorBatch(params issueTokenParams) { + timestamp, err := testSetup.mvxChainSimulator.GetBlockchainTimeStamp(testSetup.testContext) + require.Nil(testSetup, err) + require.Greater(testSetup, timestamp, uint64(0), "something went wrong and the chain simulator returned 0 for the current timestamp") + + timestampAsBigInt := big.NewInt(0).SetUint64(timestamp) + hash, err := testSetup.mvxChainSimulator.ScCall( testSetup.testContext, testSetup.mvxOwnerKeys.pk, @@ -1196,6 +1328,7 @@ func (testSetup *simulatedSetup) createEthereumSimulatorAndDeployContracts() { addr := map[common.Address]ethCore.GenesisAccount{ testSetup.ethOwnerAddress: {Balance: new(big.Int).Lsh(big.NewInt(1), 100)}, testSetup.ethDepositorAddr: {Balance: new(big.Int).Lsh(big.NewInt(1), 100)}, + testSetup.ethTestAddr: {Balance: new(big.Int).Lsh(big.NewInt(1), 100)}, } for _, relayerKeys := range testSetup.relayersKeys { addr[relayerKeys.ethAddress] = ethCore.GenesisAccount{Balance: new(big.Int).Lsh(big.NewInt(1), 100)} @@ -1239,43 +1372,90 @@ func (testSetup *simulatedSetup) createEthereumSimulatorAndDeployContracts() { } func (testSetup *simulatedSetup) issueAndWhitelistTokenOnEth(params issueTokenParams) { + erc20Address, erc20ContractInstance := testSetup.deployTestERC20Contract(params) + + testSetup.registerEthAddressAndContract(params.abstractTokenIdentifier, erc20Address, erc20ContractInstance) + + // whitelist eth token + auth, _ := bind.NewKeyedTransactorWithChainID(ethOwnerSK, testSetup.ethChainID) + tx, err := testSetup.ethSafeContract.WhitelistToken(auth, erc20Address, big.NewInt(ethMinAmountAllowedToTransfer), big.NewInt(ethMaxAmountAllowedToTransfer), params.isMintBurnOnEth, params.isNativeOnEth) + require.NoError(testSetup, err) + testSetup.simulatedETHChain.Commit() + testSetup.checkEthTxResult(tx.Hash()) +} + +func (testSetup *simulatedSetup) deployTestERC20Contract(params issueTokenParams) (common.Address, erc20Contract) { + if params.isMintBurnOnEth { + ethMintBurnAddress := testSetup.deployETHContract( + mintBurnERC20ABI, + mintBurnERC20Bytecode, + params.ethTokenName, + params.ethTokenSymbol, + params.numOfDecimalsChainSpecific, + ) + + ethMintBurnContract, err := contract.NewMintBurnERC20(ethMintBurnAddress, testSetup.simulatedETHChain) + require.NoError(testSetup, err) + + ownerAuth, _ := bind.NewKeyedTransactorWithChainID(ethOwnerSK, testSetup.ethChainID) + minterRoleBytes := [32]byte(crypto.Keccak256([]byte(minterRoleString))) + + // grant mint role to the depositor address for the initial mint + txGrantRole, err := ethMintBurnContract.GrantRole(ownerAuth, minterRoleBytes, testSetup.ethDepositorAddr) + require.NoError(testSetup, err) + testSetup.simulatedETHChain.Commit() + testSetup.checkEthTxResult(txGrantRole.Hash()) + + // grant mint role to the safe contract + txGrantRole, err = ethMintBurnContract.GrantRole(ownerAuth, minterRoleBytes, testSetup.ethSafeAddress) + require.NoError(testSetup, err) + testSetup.simulatedETHChain.Commit() + testSetup.checkEthTxResult(txGrantRole.Hash()) + + // mint generic token on the behalf of the depositor + auth, _ := bind.NewKeyedTransactorWithChainID(ethDepositorSK, testSetup.ethChainID) + + mintAmount, ok := big.NewInt(0).SetString(params.valueToMintOnEth, 10) + require.True(testSetup, ok) + tx, err := ethMintBurnContract.Mint(auth, testSetup.ethDepositorAddr, mintAmount) + require.NoError(testSetup, err) + testSetup.simulatedETHChain.Commit() + testSetup.checkEthTxResult(tx.Hash()) + + balance, err := ethMintBurnContract.BalanceOf(nil, testSetup.ethDepositorAddr) + require.NoError(testSetup, err) + require.Equal(testSetup, mintAmount.String(), balance.String()) + + return ethMintBurnAddress, ethMintBurnContract + } + // deploy generic eth token ethGenericTokenAddress := testSetup.deployETHContract( genericERC20ABI, genericERC20Bytecode, params.ethTokenName, params.ethTokenSymbol, + params.numOfDecimalsChainSpecific, ) ethGenericTokenContract, err := contract.NewGenericERC20(ethGenericTokenAddress, testSetup.simulatedETHChain) require.NoError(testSetup, err) - testSetup.registerEthAddressAndContract(params.abstractTokenIdentifier, ethGenericTokenAddress, ethGenericTokenContract) - - // mint generic token + // mint the address that will create the transfers auth, _ := bind.NewKeyedTransactorWithChainID(ethDepositorSK, testSetup.ethChainID) mintAmount, ok := big.NewInt(0).SetString(params.valueToMintOnEth, 10) require.True(testSetup, ok) - - tx, err := ethGenericTokenContract.Mint(auth, testSetup.ethDepositorAddr, mintAmount) + tx, err := ethGenericTokenContract.Mint(auth, testSetup.ethTestAddr, mintAmount) require.NoError(testSetup, err) testSetup.simulatedETHChain.Commit() testSetup.checkEthTxResult(tx.Hash()) - balance := testSetup.getEthBalance(testSetup.ethDepositorAddr, params.abstractTokenIdentifier) - - denominationFactor := big.NewInt(int64(math.Pow(10, float64(params.numOfDecimalsUniversal)))) - mintAmountWithDenomination := big.NewInt(0).Mul(mintAmount, denominationFactor) - - require.Equal(testSetup, mintAmountWithDenomination.String(), balance.String()) - - // whitelist eth token - auth, _ = bind.NewKeyedTransactorWithChainID(ethOwnerSK, testSetup.ethChainID) - tx, err = testSetup.ethSafeContract.WhitelistToken(auth, ethGenericTokenAddress, big.NewInt(ethMinAmountAllowedToTransfer), big.NewInt(ethMaxAmountAllowedToTransfer), params.isMintBurnOnEth, params.isNativeOnEth) + balance, err := ethGenericTokenContract.BalanceOf(nil, testSetup.ethTestAddr) require.NoError(testSetup, err) - testSetup.simulatedETHChain.Commit() - testSetup.checkEthTxResult(tx.Hash()) + require.Equal(testSetup, mintAmount.String(), balance.String()) + + return ethGenericTokenAddress, ethGenericTokenContract } func (testSetup *simulatedSetup) deployETHContract( @@ -1303,116 +1483,151 @@ func (testSetup *simulatedSetup) deployETHContract( return contractAddress } -func (testSetup *simulatedSetup) createBatchOnEthereum( - abstractTokenIdentifier string, - value *big.Int, - ethSCCallMethod string, - ethSCCallGasLimit uint64, - ethSCCallArguments ...string, -) { +func (testSetup *simulatedSetup) createBatchOnEthereum(tokensParams ...testTokenParams) { + for _, params := range tokensParams { + testSetup.createDepositsOnEthereumForToken(params, ethTestAddress) + } + + // wait until batch is settled + batchSettleLimit, _ := testSetup.ethSafeContract.BatchSettleLimit(nil) + for i := uint8(0); i < batchSettleLimit+1; i++ { + testSetup.simulatedETHChain.Commit() + } +} + +func (testSetup *simulatedSetup) createDepositsOnEthereumForToken(params testTokenParams, from *ecdsa.PrivateKey) { // add allowance for the sender - auth, _ := bind.NewKeyedTransactorWithChainID(ethDepositorSK, testSetup.ethChainID) + auth, _ := bind.NewKeyedTransactorWithChainID(from, testSetup.ethChainID) - token := testSetup.getTokenData(abstractTokenIdentifier) + token := testSetup.getTokenData(params.abstractTokenIdentifier) require.NotNil(testSetup, token) - require.NotNil(testSetup, token.ethGenericTokenContract) - - if len(ethSCCallMethod) > 0 { - tx, err := token.ethGenericTokenContract.Approve(auth, testSetup.ethSCProxyAddress, value) - require.NoError(testSetup, err) - testSetup.simulatedETHChain.Commit() - testSetup.checkEthTxResult(tx.Hash()) + require.NotNil(testSetup, token.ethErc20Contract) - codec := parsers.MultiversxCodec{} - callData := parsers.CallData{ - Type: parsers.DataPresentProtocolMarker, - Function: ethSCCallMethod, - GasLimit: ethSCCallGasLimit, - Arguments: ethSCCallArguments, + allowanceValueForSafe := big.NewInt(0) + allowanceValueForScProxy := big.NewInt(0) + for _, operation := range params.testOperations { + if operation.valueToTransferToMvx == nil { + continue } + if len(operation.ethSCCallMethod) > 0 { + allowanceValueForScProxy.Add(allowanceValueForScProxy, operation.valueToTransferToMvx) + } else { + allowanceValueForSafe.Add(allowanceValueForSafe, operation.valueToTransferToMvx) + } + } - buff := codec.EncodeCallData(callData) - - tx, err = testSetup.ethSCProxyContract.Deposit( - auth, - token.ethGenericTokenAddress, - value, - testSetup.mvxTestCallerAddress.AddressSlice(), - string(buff), - ) + if allowanceValueForSafe.Cmp(zeroValueBigInt) > 0 { + tx, err := token.ethErc20Contract.Approve(auth, testSetup.ethSafeAddress, allowanceValueForSafe) require.NoError(testSetup, err) testSetup.simulatedETHChain.Commit() testSetup.checkEthTxResult(tx.Hash()) - } else { - tx, err := token.ethGenericTokenContract.Approve(auth, testSetup.ethSafeAddress, value) + } + if allowanceValueForScProxy.Cmp(zeroValueBigInt) > 0 { + tx, err := token.ethErc20Contract.Approve(auth, testSetup.ethSCProxyAddress, allowanceValueForScProxy) require.NoError(testSetup, err) testSetup.simulatedETHChain.Commit() testSetup.checkEthTxResult(tx.Hash()) + } + + var err error + for _, operation := range params.testOperations { + if operation.valueToTransferToMvx == nil { + continue + } + + var tx *types.Transaction + if len(operation.ethSCCallMethod) > 0 { + codec := parsers.MultiversxCodec{} + callData := parsers.CallData{ + Type: parsers.DataPresentProtocolMarker, + Function: operation.ethSCCallMethod, + GasLimit: operation.ethSCCallGasLimit, + Arguments: operation.ethSCCallArguments, + } + + buff := codec.EncodeCallData(callData) + + tx, err = testSetup.ethSCProxyContract.Deposit( + auth, + token.ethErc20Address, + operation.valueToTransferToMvx, + testSetup.mvxTestCallerAddress.AddressSlice(), + string(buff), + ) + } else { + tx, err = testSetup.ethSafeContract.Deposit(auth, token.ethErc20Address, operation.valueToTransferToMvx, testSetup.mvxReceiverAddress.AddressSlice()) + } - // deposit on ETH safe as a simple transfer - auth, _ = bind.NewKeyedTransactorWithChainID(ethDepositorSK, testSetup.ethChainID) - tx, err = testSetup.ethSafeContract.Deposit(auth, token.ethGenericTokenAddress, value, testSetup.mvxReceiverAddress.AddressSlice()) require.NoError(testSetup, err) testSetup.simulatedETHChain.Commit() testSetup.checkEthTxResult(tx.Hash()) } +} - // wait until batch is settled - batchSettleLimit, _ := testSetup.ethSafeContract.BatchSettleLimit(nil) - for i := uint8(0); i < batchSettleLimit+1; i++ { - testSetup.simulatedETHChain.Commit() +func (testSetup *simulatedSetup) createBatchOnMultiversX(tokensParams ...testTokenParams) { + for _, params := range tokensParams { + testSetup.createBatchOnMultiversXForToken(params) } } -func (testSetup *simulatedSetup) createBatchOnMultiversX(abstractTokenIdentifier string, value *big.Int) { - token := testSetup.getTokenData(abstractTokenIdentifier) +func (testSetup *simulatedSetup) createBatchOnMultiversXForToken(params testTokenParams) { + token := testSetup.getTokenData(params.abstractTokenIdentifier) require.NotNil(testSetup, token) - require.NotNil(testSetup, token.ethGenericTokenContract) + require.NotNil(testSetup, token.ethErc20Contract) - // mint erc20 token into eth safe - auth, _ := bind.NewKeyedTransactorWithChainID(ethDepositorSK, testSetup.ethChainID) - tx, err := token.ethGenericTokenContract.Mint(auth, testSetup.ethSafeAddress, value) - require.NoError(testSetup, err) - testSetup.simulatedETHChain.Commit() - testSetup.checkEthTxResult(tx.Hash()) + valueToMintOnEthereum := big.NewInt(0) + for _, operation := range params.testOperations { + if operation.valueToSendFromMvX == nil { + continue + } - // transfer to sender tx - hash, err := testSetup.mvxChainSimulator.ScCall( - testSetup.testContext, - testSetup.mvxOwnerKeys.pk, - testSetup.mvxOwnerKeys.sk, - testSetup.mvxReceiverKeys.pk, - zeroValue, - esdtTransfer, - []string{ - hex.EncodeToString([]byte(token.mvxChainSpecificToken)), - hex.EncodeToString(value.Bytes())}) - require.NoError(testSetup, err) - txResult, err := testSetup.mvxChainSimulator.GetTransactionResult(testSetup.testContext, hash) - require.NoError(testSetup, err) + valueToMintOnEthereum.Add(valueToMintOnEthereum, operation.valueToSendFromMvX) + + // transfer to sender tx + hash, err := testSetup.mvxChainSimulator.ScCall( + testSetup.testContext, + testSetup.mvxOwnerKeys.pk, + testSetup.mvxOwnerKeys.sk, + testSetup.mvxReceiverKeys.pk, + zeroValue, + esdtTransfer, + []string{ + hex.EncodeToString([]byte(token.mvxChainSpecificToken)), + hex.EncodeToString(operation.valueToSendFromMvX.Bytes())}) + require.NoError(testSetup, err) + txResult, err := testSetup.mvxChainSimulator.GetTransactionResult(testSetup.testContext, hash) + require.NoError(testSetup, err) - log.Info("transfer to sender tx executed", "hash", hash, "status", txResult.Status) + log.Info("transfer to sender tx executed", "hash", hash, "status", txResult.Status) - // send tx to safe contract - params := []string{ - hex.EncodeToString([]byte(token.mvxChainSpecificToken)), - hex.EncodeToString(value.Bytes()), - hex.EncodeToString([]byte(createTransactionParam)), - hex.EncodeToString(testSetup.ethOwnerAddress.Bytes()), + // send tx to safe contract + scCallParams := []string{ + hex.EncodeToString([]byte(token.mvxChainSpecificToken)), + hex.EncodeToString(operation.valueToSendFromMvX.Bytes()), + hex.EncodeToString([]byte(createTransactionParam)), + hex.EncodeToString(testSetup.ethTestAddr.Bytes()), + } + hash, err = testSetup.mvxChainSimulator.ScCall( + testSetup.testContext, + testSetup.mvxReceiverKeys.pk, + testSetup.mvxReceiverKeys.sk, + testSetup.mvxSafeAddressString, + zeroValue, + esdtTransfer, + scCallParams) + require.NoError(testSetup, err) + txResult, err = testSetup.mvxChainSimulator.GetTransactionResult(testSetup.testContext, hash) + require.NoError(testSetup, err) + + log.Info("MultiversX->Ethereum transaction sent", "hash", hash, "status", txResult.Status) } - hash, err = testSetup.mvxChainSimulator.ScCall( - testSetup.testContext, - testSetup.mvxReceiverKeys.pk, - testSetup.mvxReceiverKeys.sk, - testSetup.mvxSafeAddressString, - zeroValue, - esdtTransfer, - params) - require.NoError(testSetup, err) - txResult, err = testSetup.mvxChainSimulator.GetTransactionResult(testSetup.testContext, hash) - require.NoError(testSetup, err) - log.Info("MVX->ETH transaction sent", "hash", hash, "status", txResult.Status) + // mint erc20 token into eth safe + auth, _ := bind.NewKeyedTransactorWithChainID(ethDepositorSK, testSetup.ethChainID) + tx, err := token.ethErc20Contract.Mint(auth, testSetup.ethSafeAddress, valueToMintOnEthereum) + require.NoError(testSetup, err) + testSetup.simulatedETHChain.Commit() + testSetup.checkEthTxResult(tx.Hash()) } func (testSetup *simulatedSetup) checkEthTxResult(hash common.Hash) { diff --git a/integrationTests/relayers/slowTests/startsFromEthereumFlow.go b/integrationTests/relayers/slowTests/startsFromEthereumFlow.go new file mode 100644 index 00000000..0279d74e --- /dev/null +++ b/integrationTests/relayers/slowTests/startsFromEthereumFlow.go @@ -0,0 +1,43 @@ +//go:build slow + +package slowTests + +import "testing" + +type startsFromEthereumFlow struct { + testing.TB + testSetup *simulatedSetup + ethToMvxDone bool + mvxToEthDone bool + tokens []testTokenParams +} + +func (flow *startsFromEthereumFlow) process() (finished bool) { + if len(flow.tokens) == 0 { + return true + } + if flow.mvxToEthDone && flow.ethToMvxDone { + return true + } + + isTransferDoneFromEthereum := flow.testSetup.isTransferDoneFromEthereum(flow.tokens...) + if !flow.ethToMvxDone && isTransferDoneFromEthereum { + flow.ethToMvxDone = true + log.Info("Ethereum->MultiversX transfer finished, now sending back to Ethereum...") + + flow.testSetup.sendFromMultiversxToEthereum(flow.tokens...) + } + if !flow.ethToMvxDone { + // return here, no reason to check downwards + return false + } + + isTransferDoneFromMultiversX := flow.testSetup.isTransferDoneFromMultiversX(flow.tokens...) + if !flow.mvxToEthDone && isTransferDoneFromMultiversX { + flow.mvxToEthDone = true + log.Info("MultiversX<->Ethereum transfers done") + return true + } + + return false +} diff --git a/integrationTests/relayers/slowTests/startsFromMultiversxFlow.go b/integrationTests/relayers/slowTests/startsFromMultiversxFlow.go new file mode 100644 index 00000000..89b5015f --- /dev/null +++ b/integrationTests/relayers/slowTests/startsFromMultiversxFlow.go @@ -0,0 +1,43 @@ +//go:build slow + +package slowTests + +import "testing" + +type startsFromMultiversXFlow struct { + testing.TB + testSetup *simulatedSetup + ethToMvxDone bool + mvxToEthDone bool + tokens []testTokenParams +} + +func (flow *startsFromMultiversXFlow) process() (finished bool) { + if len(flow.tokens) == 0 { + return true + } + if flow.mvxToEthDone && flow.ethToMvxDone { + return true + } + + isTransferDoneFromMultiversX := flow.testSetup.isTransferDoneFromMultiversX(flow.tokens...) + if !flow.mvxToEthDone && isTransferDoneFromMultiversX { + flow.mvxToEthDone = true + log.Info("MultiversX->Ethereum transfer finished, now sending back to MultiversX...") + + flow.testSetup.sendFromEthereumToMultiversX(flow.tokens...) + } + if !flow.mvxToEthDone { + // return here, no reason to check downwards + return false + } + + isTransferDoneFromEthereum := flow.testSetup.isTransferDoneFromEthereum(flow.tokens...) + if !flow.ethToMvxDone && isTransferDoneFromEthereum { + flow.ethToMvxDone = true + log.Info("MultiversX<->Ethereum transfers done") + return true + } + + return false +} diff --git a/integrationTests/relayers/slowTests/testdata/contracts/eth/Bridge.json b/integrationTests/relayers/slowTests/testdata/contracts/eth/Bridge.abi.json similarity index 100% rename from integrationTests/relayers/slowTests/testdata/contracts/eth/Bridge.json rename to integrationTests/relayers/slowTests/testdata/contracts/eth/Bridge.abi.json diff --git a/integrationTests/relayers/slowTests/testdata/contracts/eth/ERC20Safe.json b/integrationTests/relayers/slowTests/testdata/contracts/eth/ERC20Safe.abi.json similarity index 100% rename from integrationTests/relayers/slowTests/testdata/contracts/eth/ERC20Safe.json rename to integrationTests/relayers/slowTests/testdata/contracts/eth/ERC20Safe.abi.json diff --git a/integrationTests/relayers/slowTests/testdata/contracts/eth/GenericERC20.json b/integrationTests/relayers/slowTests/testdata/contracts/eth/GenericERC20.abi.json similarity index 98% rename from integrationTests/relayers/slowTests/testdata/contracts/eth/GenericERC20.json rename to integrationTests/relayers/slowTests/testdata/contracts/eth/GenericERC20.abi.json index f31fe1cd..5bbc1c07 100644 --- a/integrationTests/relayers/slowTests/testdata/contracts/eth/GenericERC20.json +++ b/integrationTests/relayers/slowTests/testdata/contracts/eth/GenericERC20.abi.json @@ -10,6 +10,11 @@ "internalType": "string", "name": "tokenSymbol", "type": "string" + }, + { + "internalType": "uint8", + "name": "providedNumDecimals", + "type": "uint8" } ], "stateMutability": "nonpayable", diff --git a/integrationTests/relayers/slowTests/testdata/contracts/eth/GenericERC20.hex b/integrationTests/relayers/slowTests/testdata/contracts/eth/GenericERC20.hex index 350ca896..48c2d280 100644 --- a/integrationTests/relayers/slowTests/testdata/contracts/eth/GenericERC20.hex +++ b/integrationTests/relayers/slowTests/testdata/contracts/eth/GenericERC20.hex @@ -1 +1 @@ -0x60806040523480156200001157600080fd5b5060405162000b7a38038062000b7a833981016040819052620000349162000123565b818160036200004483826200021c565b5060046200005382826200021c565b5050505050620002e8565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200008657600080fd5b81516001600160401b0380821115620000a357620000a36200005e565b604051601f8301601f19908116603f01168101908282118183101715620000ce57620000ce6200005e565b81604052838152602092508683858801011115620000eb57600080fd5b600091505b838210156200010f5785820183015181830184015290820190620000f0565b600093810190920192909252949350505050565b600080604083850312156200013757600080fd5b82516001600160401b03808211156200014f57600080fd5b6200015d8683870162000074565b935060208501519150808211156200017457600080fd5b50620001838582860162000074565b9150509250929050565b600181811c90821680620001a257607f821691505b602082108103620001c357634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200021757600081815260208120601f850160051c81016020861015620001f25750805b601f850160051c820191505b818110156200021357828155600101620001fe565b5050505b505050565b81516001600160401b038111156200023857620002386200005e565b62000250816200024984546200018d565b84620001c9565b602080601f8311600181146200028857600084156200026f5750858301515b600019600386901b1c1916600185901b17855562000213565b600085815260208120601f198616915b82811015620002b95788860151825594840194600190910190840162000298565b5085821015620002d85787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b61088280620002f86000396000f3fe608060405234801561001057600080fd5b506004361061009e5760003560e01c806340c10f191161006657806340c10f191461011857806370a082311461012d57806395d89b4114610156578063a9059cbb1461015e578063dd62ed3e1461017157600080fd5b806306fdde03146100a3578063095ea7b3146100c157806318160ddd146100e457806323b872dd146100f6578063313ce56714610109575b600080fd5b6100ab6101aa565b6040516100b891906105e3565b60405180910390f35b6100d46100cf36600461064d565b61023c565b60405190151581526020016100b8565b6002545b6040519081526020016100b8565b6100d4610104366004610677565b610256565b604051600681526020016100b8565b61012b61012636600461064d565b61027a565b005b6100e861013b3660046106b3565b6001600160a01b031660009081526020819052604090205490565b6100ab61029d565b6100d461016c36600461064d565b6102ac565b6100e861017f3660046106d5565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6060600380546101b990610708565b80601f01602080910402602001604051908101604052809291908181526020018280546101e590610708565b80156102325780601f1061020757610100808354040283529160200191610232565b820191906000526020600020905b81548152906001019060200180831161021557829003601f168201915b5050505050905090565b60003361024a8185856102ba565b60019150505b92915050565b6000336102648582856102cc565b61026f85858561034f565b506001949350505050565b6102998261028a6006600a61083c565b610294908461084b565b6103ae565b5050565b6060600480546101b990610708565b60003361024a81858561034f565b6102c783838360016103e4565b505050565b6001600160a01b038381166000908152600160209081526040808320938616835292905220546000198114610349578181101561033a57604051637dc7a0d960e11b81526001600160a01b038416600482015260248101829052604481018390526064015b60405180910390fd5b610349848484840360006103e4565b50505050565b6001600160a01b03831661037957604051634b637e8f60e11b815260006004820152602401610331565b6001600160a01b0382166103a35760405163ec442f0560e01b815260006004820152602401610331565b6102c78383836104b9565b6001600160a01b0382166103d85760405163ec442f0560e01b815260006004820152602401610331565b610299600083836104b9565b6001600160a01b03841661040e5760405163e602df0560e01b815260006004820152602401610331565b6001600160a01b03831661043857604051634a1406b160e11b815260006004820152602401610331565b6001600160a01b038085166000908152600160209081526040808320938716835292905220829055801561034957826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516104ab91815260200190565b60405180910390a350505050565b6001600160a01b0383166104e45780600260008282546104d99190610862565b909155506105569050565b6001600160a01b038316600090815260208190526040902054818110156105375760405163391434e360e21b81526001600160a01b03851660048201526024810182905260448101839052606401610331565b6001600160a01b03841660009081526020819052604090209082900390555b6001600160a01b03821661057257600280548290039055610591565b6001600160a01b03821660009081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516105d691815260200190565b60405180910390a3505050565b600060208083528351808285015260005b81811015610610578581018301518582016040015282016105f4565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b038116811461064857600080fd5b919050565b6000806040838503121561066057600080fd5b61066983610631565b946020939093013593505050565b60008060006060848603121561068c57600080fd5b61069584610631565b92506106a360208501610631565b9150604084013590509250925092565b6000602082840312156106c557600080fd5b6106ce82610631565b9392505050565b600080604083850312156106e857600080fd5b6106f183610631565b91506106ff60208401610631565b90509250929050565b600181811c9082168061071c57607f821691505b60208210810361073c57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b600181815b8085111561079357816000190482111561077957610779610742565b8085161561078657918102915b93841c939080029061075d565b509250929050565b6000826107aa57506001610250565b816107b757506000610250565b81600181146107cd57600281146107d7576107f3565b6001915050610250565b60ff8411156107e8576107e8610742565b50506001821b610250565b5060208310610133831016604e8410600b8410161715610816575081810a610250565b6108208383610758565b806000190482111561083457610834610742565b029392505050565b60006106ce60ff84168361079b565b808202811582820484141761025057610250610742565b808201808211156102505761025061074256fea164736f6c6343000814000a +0x60806040523480156200001157600080fd5b5060405162000a8a38038062000a8a833981016040819052620000349162000139565b828260036200004483826200024d565b5060046200005382826200024d565b50506005805460ff191660ff93909316929092179091555062000319915050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200009c57600080fd5b81516001600160401b0380821115620000b957620000b962000074565b604051601f8301601f19908116603f01168101908282118183101715620000e457620000e462000074565b816040528381526020925086838588010111156200010157600080fd5b600091505b8382101562000125578582018301518183018401529082019062000106565b600093810190920192909252949350505050565b6000806000606084860312156200014f57600080fd5b83516001600160401b03808211156200016757600080fd5b62000175878388016200008a565b945060208601519150808211156200018c57600080fd5b506200019b868287016200008a565b925050604084015160ff81168114620001b357600080fd5b809150509250925092565b600181811c90821680620001d357607f821691505b602082108103620001f457634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200024857600081815260208120601f850160051c81016020861015620002235750805b601f850160051c820191505b8181101562000244578281556001016200022f565b5050505b505050565b81516001600160401b0381111562000269576200026962000074565b62000281816200027a8454620001be565b84620001fa565b602080601f831160018114620002b95760008415620002a05750858301515b600019600386901b1c1916600185901b17855562000244565b600085815260208120601f198616915b82811015620002ea57888601518255948401946001909101908401620002c9565b5085821015620003095787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b61076180620003296000396000f3fe608060405234801561001057600080fd5b506004361061009e5760003560e01c806340c10f191161006657806340c10f191461011e57806370a082311461013357806395d89b411461015c578063a9059cbb14610164578063dd62ed3e1461017757600080fd5b806306fdde03146100a3578063095ea7b3146100c157806318160ddd146100e457806323b872dd146100f6578063313ce56714610109575b600080fd5b6100ab6101b0565b6040516100b891906105d4565b60405180910390f35b6100d46100cf36600461063e565b610242565b60405190151581526020016100b8565b6002545b6040519081526020016100b8565b6100d4610104366004610668565b61025c565b60055460405160ff90911681526020016100b8565b61013161012c36600461063e565b610280565b005b6100e86101413660046106a4565b6001600160a01b031660009081526020819052604090205490565b6100ab61028e565b6100d461017236600461063e565b61029d565b6100e86101853660046106c6565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6060600380546101bf906106f9565b80601f01602080910402602001604051908101604052809291908181526020018280546101eb906106f9565b80156102385780601f1061020d57610100808354040283529160200191610238565b820191906000526020600020905b81548152906001019060200180831161021b57829003601f168201915b5050505050905090565b6000336102508185856102ab565b60019150505b92915050565b60003361026a8582856102bd565b610275858585610340565b506001949350505050565b61028a828261039f565b5050565b6060600480546101bf906106f9565b600033610250818585610340565b6102b883838360016103d5565b505050565b6001600160a01b03838116600090815260016020908152604080832093861683529290522054600019811461033a578181101561032b57604051637dc7a0d960e11b81526001600160a01b038416600482015260248101829052604481018390526064015b60405180910390fd5b61033a848484840360006103d5565b50505050565b6001600160a01b03831661036a57604051634b637e8f60e11b815260006004820152602401610322565b6001600160a01b0382166103945760405163ec442f0560e01b815260006004820152602401610322565b6102b88383836104aa565b6001600160a01b0382166103c95760405163ec442f0560e01b815260006004820152602401610322565b61028a600083836104aa565b6001600160a01b0384166103ff5760405163e602df0560e01b815260006004820152602401610322565b6001600160a01b03831661042957604051634a1406b160e11b815260006004820152602401610322565b6001600160a01b038085166000908152600160209081526040808320938716835292905220829055801561033a57826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161049c91815260200190565b60405180910390a350505050565b6001600160a01b0383166104d55780600260008282546104ca9190610733565b909155506105479050565b6001600160a01b038316600090815260208190526040902054818110156105285760405163391434e360e21b81526001600160a01b03851660048201526024810182905260448101839052606401610322565b6001600160a01b03841660009081526020819052604090209082900390555b6001600160a01b03821661056357600280548290039055610582565b6001600160a01b03821660009081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516105c791815260200190565b60405180910390a3505050565b600060208083528351808285015260005b81811015610601578581018301518582016040015282016105e5565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b038116811461063957600080fd5b919050565b6000806040838503121561065157600080fd5b61065a83610622565b946020939093013593505050565b60008060006060848603121561067d57600080fd5b61068684610622565b925061069460208501610622565b9150604084013590509250925092565b6000602082840312156106b657600080fd5b6106bf82610622565b9392505050565b600080604083850312156106d957600080fd5b6106e283610622565b91506106f060208401610622565b90509250929050565b600181811c9082168061070d57607f821691505b60208210810361072d57634e487b7160e01b600052602260045260246000fd5b50919050565b8082018082111561025657634e487b7160e01b600052601160045260246000fdfea164736f6c6343000814000a diff --git a/integrationTests/relayers/slowTests/testdata/contracts/eth/MintBurnERC20.json b/integrationTests/relayers/slowTests/testdata/contracts/eth/MintBurnERC20.abi.json similarity index 99% rename from integrationTests/relayers/slowTests/testdata/contracts/eth/MintBurnERC20.json rename to integrationTests/relayers/slowTests/testdata/contracts/eth/MintBurnERC20.abi.json index 3e6e7528..ecf8b0d1 100644 --- a/integrationTests/relayers/slowTests/testdata/contracts/eth/MintBurnERC20.json +++ b/integrationTests/relayers/slowTests/testdata/contracts/eth/MintBurnERC20.abi.json @@ -10,6 +10,11 @@ "internalType": "string", "name": "symbol", "type": "string" + }, + { + "internalType": "uint8", + "name": "providedNumDecimals", + "type": "uint8" } ], "stateMutability": "nonpayable", diff --git a/integrationTests/relayers/slowTests/testdata/contracts/eth/MintBurnERC20.hex b/integrationTests/relayers/slowTests/testdata/contracts/eth/MintBurnERC20.hex index 22acae39..a1f14808 100644 --- a/integrationTests/relayers/slowTests/testdata/contracts/eth/MintBurnERC20.hex +++ b/integrationTests/relayers/slowTests/testdata/contracts/eth/MintBurnERC20.hex @@ -1 +1 @@ -0x60806040523480156200001157600080fd5b5060405162000f9f38038062000f9f8339810160408190526200003491620001e6565b81816003620000448382620002df565b506004620000538282620002df565b5062000065915060009050336200006e565b505050620003ab565b60008281526005602090815260408083206001600160a01b038516845290915281205460ff16620001175760008381526005602090815260408083206001600160a01b03861684529091529020805460ff19166001179055620000ce3390565b6001600160a01b0316826001600160a01b0316847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45060016200011b565b5060005b92915050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200014957600080fd5b81516001600160401b038082111562000166576200016662000121565b604051601f8301601f19908116603f0116810190828211818310171562000191576200019162000121565b81604052838152602092508683858801011115620001ae57600080fd5b600091505b83821015620001d25785820183015181830184015290820190620001b3565b600093810190920192909252949350505050565b60008060408385031215620001fa57600080fd5b82516001600160401b03808211156200021257600080fd5b620002208683870162000137565b935060208501519150808211156200023757600080fd5b50620002468582860162000137565b9150509250929050565b600181811c908216806200026557607f821691505b6020821081036200028657634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620002da57600081815260208120601f850160051c81016020861015620002b55750805b601f850160051c820191505b81811015620002d657828155600101620002c1565b5050505b505050565b81516001600160401b03811115620002fb57620002fb62000121565b62000313816200030c845462000250565b846200028c565b602080601f8311600181146200034b5760008415620003325750858301515b600019600386901b1c1916600185901b178555620002d6565b600085815260208120601f198616915b828110156200037c578886015182559484019460019091019084016200035b565b50858210156200039b5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b610be480620003bb6000396000f3fe608060405234801561001057600080fd5b506004361061012c5760003560e01c806342966c68116100ad578063a217fddf11610071578063a217fddf1461027d578063a9059cbb14610285578063d539139314610298578063d547741f146102bf578063dd62ed3e146102d257600080fd5b806342966c681461021357806370a082311461022657806379cc67901461024f57806391d148541461026257806395d89b411461027557600080fd5b8063248a9ca3116100f4578063248a9ca3146101a65780632f2ff15d146101c9578063313ce567146101de57806336568abe146101ed57806340c10f191461020057600080fd5b806301ffc9a71461013157806306fdde0314610159578063095ea7b31461016e57806318160ddd1461018157806323b872dd14610193575b600080fd5b61014461013f3660046109f1565b61030b565b60405190151581526020015b60405180910390f35b610161610342565b6040516101509190610a22565b61014461017c366004610a8c565b6103d4565b6002545b604051908152602001610150565b6101446101a1366004610ab6565b6103ec565b6101856101b4366004610af2565b60009081526005602052604090206001015490565b6101dc6101d7366004610b0b565b610410565b005b60405160128152602001610150565b6101dc6101fb366004610b0b565b61043b565b6101dc61020e366004610a8c565b610473565b6101dc610221366004610af2565b6104cf565b610185610234366004610b37565b6001600160a01b031660009081526020819052604090205490565b6101dc61025d366004610a8c565b6104dc565b610144610270366004610b0b565b6104f1565b61016161051c565b610185600081565b610144610293366004610a8c565b61052b565b6101857f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b6101dc6102cd366004610b0b565b610539565b6101856102e0366004610b52565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60006001600160e01b03198216637965db0b60e01b148061033c57506301ffc9a760e01b6001600160e01b03198316145b92915050565b60606003805461035190610b7c565b80601f016020809104026020016040519081016040528092919081815260200182805461037d90610b7c565b80156103ca5780601f1061039f576101008083540402835291602001916103ca565b820191906000526020600020905b8154815290600101906020018083116103ad57829003601f168201915b5050505050905090565b6000336103e281858561055e565b5060019392505050565b6000336103fa85828561056b565b6104058585856105e3565b506001949350505050565b60008281526005602052604090206001015461042b81610642565b610435838361064c565b50505050565b6001600160a01b03811633146104645760405163334bd91960e11b815260040160405180910390fd5b61046e82826106e0565b505050565b61049d7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6336104f1565b6104c157604051632fdab94f60e11b81523360048201526024015b60405180910390fd5b6104cb828261074d565b5050565b6104d93382610783565b50565b6104e782338361056b565b6104cb8282610783565b60009182526005602090815260408084206001600160a01b0393909316845291905290205460ff1690565b60606004805461035190610b7c565b6000336103e28185856105e3565b60008281526005602052604090206001015461055481610642565b61043583836106e0565b61046e83838360016107b9565b6001600160a01b03838116600090815260016020908152604080832093861683529290522054600019811461043557818110156105d457604051637dc7a0d960e11b81526001600160a01b038416600482015260248101829052604481018390526064016104b8565b610435848484840360006107b9565b6001600160a01b03831661060d57604051634b637e8f60e11b8152600060048201526024016104b8565b6001600160a01b0382166106375760405163ec442f0560e01b8152600060048201526024016104b8565b61046e83838361088e565b6104d981336109b8565b600061065883836104f1565b6106d85760008381526005602090815260408083206001600160a01b03861684529091529020805460ff191660011790556106903390565b6001600160a01b0316826001600160a01b0316847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a450600161033c565b50600061033c565b60006106ec83836104f1565b156106d85760008381526005602090815260408083206001600160a01b0386168085529252808320805460ff1916905551339286917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a450600161033c565b6001600160a01b0382166107775760405163ec442f0560e01b8152600060048201526024016104b8565b6104cb6000838361088e565b6001600160a01b0382166107ad57604051634b637e8f60e11b8152600060048201526024016104b8565b6104cb8260008361088e565b6001600160a01b0384166107e35760405163e602df0560e01b8152600060048201526024016104b8565b6001600160a01b03831661080d57604051634a1406b160e11b8152600060048201526024016104b8565b6001600160a01b038085166000908152600160209081526040808320938716835292905220829055801561043557826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161088091815260200190565b60405180910390a350505050565b6001600160a01b0383166108b95780600260008282546108ae9190610bb6565b9091555061092b9050565b6001600160a01b0383166000908152602081905260409020548181101561090c5760405163391434e360e21b81526001600160a01b038516600482015260248101829052604481018390526064016104b8565b6001600160a01b03841660009081526020819052604090209082900390555b6001600160a01b03821661094757600280548290039055610966565b6001600160a01b03821660009081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516109ab91815260200190565b60405180910390a3505050565b6109c282826104f1565b6104cb5760405163e2517d3f60e01b81526001600160a01b0382166004820152602481018390526044016104b8565b600060208284031215610a0357600080fd5b81356001600160e01b031981168114610a1b57600080fd5b9392505050565b600060208083528351808285015260005b81811015610a4f57858101830151858201604001528201610a33565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b0381168114610a8757600080fd5b919050565b60008060408385031215610a9f57600080fd5b610aa883610a70565b946020939093013593505050565b600080600060608486031215610acb57600080fd5b610ad484610a70565b9250610ae260208501610a70565b9150604084013590509250925092565b600060208284031215610b0457600080fd5b5035919050565b60008060408385031215610b1e57600080fd5b82359150610b2e60208401610a70565b90509250929050565b600060208284031215610b4957600080fd5b610a1b82610a70565b60008060408385031215610b6557600080fd5b610b6e83610a70565b9150610b2e60208401610a70565b600181811c90821680610b9057607f821691505b602082108103610bb057634e487b7160e01b600052602260045260246000fd5b50919050565b8082018082111561033c57634e487b7160e01b600052601160045260246000fdfea164736f6c6343000814000a +0x60806040523480156200001157600080fd5b5060405162000fce38038062000fce8339810160408190526200003491620001f4565b8282600362000044838262000308565b50600462000053828262000308565b50506006805460ff191660ff841617905550620000726000336200007c565b50505050620003d4565b60008281526005602090815260408083206001600160a01b038516845290915281205460ff16620001255760008381526005602090815260408083206001600160a01b03861684529091529020805460ff19166001179055620000dc3390565b6001600160a01b0316826001600160a01b0316847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a450600162000129565b5060005b92915050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200015757600080fd5b81516001600160401b03808211156200017457620001746200012f565b604051601f8301601f19908116603f011681019082821181831017156200019f576200019f6200012f565b81604052838152602092508683858801011115620001bc57600080fd5b600091505b83821015620001e05785820183015181830184015290820190620001c1565b600093810190920192909252949350505050565b6000806000606084860312156200020a57600080fd5b83516001600160401b03808211156200022257600080fd5b620002308783880162000145565b945060208601519150808211156200024757600080fd5b50620002568682870162000145565b925050604084015160ff811681146200026e57600080fd5b809150509250925092565b600181811c908216806200028e57607f821691505b602082108103620002af57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200030357600081815260208120601f850160051c81016020861015620002de5750805b601f850160051c820191505b81811015620002ff57828155600101620002ea565b5050505b505050565b81516001600160401b038111156200032457620003246200012f565b6200033c8162000335845462000279565b84620002b5565b602080601f8311600181146200037457600084156200035b5750858301515b600019600386901b1c1916600185901b178555620002ff565b600085815260208120601f198616915b82811015620003a55788860151825594840194600190910190840162000384565b5085821015620003c45787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b610bea80620003e46000396000f3fe608060405234801561001057600080fd5b506004361061012c5760003560e01c806342966c68116100ad578063a217fddf11610071578063a217fddf14610283578063a9059cbb1461028b578063d53913931461029e578063d547741f146102c5578063dd62ed3e146102d857600080fd5b806342966c681461021957806370a082311461022c57806379cc67901461025557806391d148541461026857806395d89b411461027b57600080fd5b8063248a9ca3116100f4578063248a9ca3146101a65780632f2ff15d146101c9578063313ce567146101de57806336568abe146101f357806340c10f191461020657600080fd5b806301ffc9a71461013157806306fdde0314610159578063095ea7b31461016e57806318160ddd1461018157806323b872dd14610193575b600080fd5b61014461013f3660046109f7565b610311565b60405190151581526020015b60405180910390f35b610161610348565b6040516101509190610a28565b61014461017c366004610a92565b6103da565b6002545b604051908152602001610150565b6101446101a1366004610abc565b6103f2565b6101856101b4366004610af8565b60009081526005602052604090206001015490565b6101dc6101d7366004610b11565b610416565b005b60065460405160ff9091168152602001610150565b6101dc610201366004610b11565b610441565b6101dc610214366004610a92565b610479565b6101dc610227366004610af8565b6104d5565b61018561023a366004610b3d565b6001600160a01b031660009081526020819052604090205490565b6101dc610263366004610a92565b6104e2565b610144610276366004610b11565b6104f7565b610161610522565b610185600081565b610144610299366004610a92565b610531565b6101857f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b6101dc6102d3366004610b11565b61053f565b6101856102e6366004610b58565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60006001600160e01b03198216637965db0b60e01b148061034257506301ffc9a760e01b6001600160e01b03198316145b92915050565b60606003805461035790610b82565b80601f016020809104026020016040519081016040528092919081815260200182805461038390610b82565b80156103d05780601f106103a5576101008083540402835291602001916103d0565b820191906000526020600020905b8154815290600101906020018083116103b357829003601f168201915b5050505050905090565b6000336103e8818585610564565b5060019392505050565b600033610400858285610571565b61040b8585856105e9565b506001949350505050565b60008281526005602052604090206001015461043181610648565b61043b8383610652565b50505050565b6001600160a01b038116331461046a5760405163334bd91960e11b815260040160405180910390fd5b61047482826106e6565b505050565b6104a37f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6336104f7565b6104c757604051632fdab94f60e11b81523360048201526024015b60405180910390fd5b6104d18282610753565b5050565b6104df3382610789565b50565b6104ed823383610571565b6104d18282610789565b60009182526005602090815260408084206001600160a01b0393909316845291905290205460ff1690565b60606004805461035790610b82565b6000336103e88185856105e9565b60008281526005602052604090206001015461055a81610648565b61043b83836106e6565b61047483838360016107bf565b6001600160a01b03838116600090815260016020908152604080832093861683529290522054600019811461043b57818110156105da57604051637dc7a0d960e11b81526001600160a01b038416600482015260248101829052604481018390526064016104be565b61043b848484840360006107bf565b6001600160a01b03831661061357604051634b637e8f60e11b8152600060048201526024016104be565b6001600160a01b03821661063d5760405163ec442f0560e01b8152600060048201526024016104be565b610474838383610894565b6104df81336109be565b600061065e83836104f7565b6106de5760008381526005602090815260408083206001600160a01b03861684529091529020805460ff191660011790556106963390565b6001600160a01b0316826001600160a01b0316847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a4506001610342565b506000610342565b60006106f283836104f7565b156106de5760008381526005602090815260408083206001600160a01b0386168085529252808320805460ff1916905551339286917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a4506001610342565b6001600160a01b03821661077d5760405163ec442f0560e01b8152600060048201526024016104be565b6104d160008383610894565b6001600160a01b0382166107b357604051634b637e8f60e11b8152600060048201526024016104be565b6104d182600083610894565b6001600160a01b0384166107e95760405163e602df0560e01b8152600060048201526024016104be565b6001600160a01b03831661081357604051634a1406b160e11b8152600060048201526024016104be565b6001600160a01b038085166000908152600160209081526040808320938716835292905220829055801561043b57826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161088691815260200190565b60405180910390a350505050565b6001600160a01b0383166108bf5780600260008282546108b49190610bbc565b909155506109319050565b6001600160a01b038316600090815260208190526040902054818110156109125760405163391434e360e21b81526001600160a01b038516600482015260248101829052604481018390526064016104be565b6001600160a01b03841660009081526020819052604090209082900390555b6001600160a01b03821661094d5760028054829003905561096c565b6001600160a01b03821660009081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516109b191815260200190565b60405180910390a3505050565b6109c882826104f7565b6104d15760405163e2517d3f60e01b81526001600160a01b0382166004820152602481018390526044016104be565b600060208284031215610a0957600080fd5b81356001600160e01b031981168114610a2157600080fd5b9392505050565b600060208083528351808285015260005b81811015610a5557858101830151858201604001528201610a39565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b0381168114610a8d57600080fd5b919050565b60008060408385031215610aa557600080fd5b610aae83610a76565b946020939093013593505050565b600080600060608486031215610ad157600080fd5b610ada84610a76565b9250610ae860208501610a76565b9150604084013590509250925092565b600060208284031215610b0a57600080fd5b5035919050565b60008060408385031215610b2457600080fd5b82359150610b3460208401610a76565b90509250929050565b600060208284031215610b4f57600080fd5b610a2182610a76565b60008060408385031215610b6b57600080fd5b610b7483610a76565b9150610b3460208401610a76565b600181811c90821680610b9657607f821691505b602082108103610bb657634e487b7160e01b600052602260045260246000fd5b50919050565b8082018082111561034257634e487b7160e01b600052601160045260246000fdfea164736f6c6343000814000a diff --git a/integrationTests/relayers/slowTests/testdata/contracts/eth/SCExecProxy.json b/integrationTests/relayers/slowTests/testdata/contracts/eth/SCExecProxy.abi.json similarity index 100% rename from integrationTests/relayers/slowTests/testdata/contracts/eth/SCExecProxy.json rename to integrationTests/relayers/slowTests/testdata/contracts/eth/SCExecProxy.abi.json diff --git a/integrationTests/relayers/slowTests/tokensRegistry.go b/integrationTests/relayers/slowTests/tokensRegistry.go index 70d19644..08e2ee7c 100644 --- a/integrationTests/relayers/slowTests/tokensRegistry.go +++ b/integrationTests/relayers/slowTests/tokensRegistry.go @@ -7,7 +7,6 @@ import ( "testing" "github.com/ethereum/go-ethereum/common" - "github.com/multiversx/mx-bridge-eth-go/clients/ethereum/contract" "github.com/stretchr/testify/require" ) @@ -19,10 +18,10 @@ type tokenData struct { ethTokenName string ethTokenSymbol string - mvxUniversalToken string - mvxChainSpecificToken string - ethGenericTokenAddress common.Address - ethGenericTokenContract *contract.GenericERC20 + mvxUniversalToken string + mvxChainSpecificToken string + ethErc20Address common.Address + ethErc20Contract erc20Contract } type tokensRegistry struct { @@ -78,8 +77,8 @@ func (registry *tokensRegistry) registerChainSpecificToken(abstractTokenIdentifi func (registry *tokensRegistry) registerEthAddressAndContract( abstractTokenIdentifier string, - ethGenericTokenAddress common.Address, - ethGenericTokenContract *contract.GenericERC20, + ethErc20Address common.Address, + ethErc20Contract erc20Contract, ) { registry.mut.Lock() defer registry.mut.Unlock() @@ -87,8 +86,8 @@ func (registry *tokensRegistry) registerEthAddressAndContract( data, found := registry.tokens[abstractTokenIdentifier] require.True(registry, found, "abstract token identifier not registered %s", abstractTokenIdentifier) - data.ethGenericTokenAddress = ethGenericTokenAddress - data.ethGenericTokenContract = ethGenericTokenContract + data.ethErc20Address = ethErc20Address + data.ethErc20Contract = ethErc20Contract } func (registry *tokensRegistry) getTokenData(abstractTokenIdentifier string) *tokenData {