Skip to content
This repository has been archived by the owner on Jan 15, 2024. It is now read-only.

Check ERC20 address matches registered address #968

Merged
merged 2 commits into from
Apr 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions contracts/contracts/CAPE.sol
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ contract CAPE is RecordsMerkleTree, RootStore, AssetRegistry, ReentrancyGuard {
/// @param erc20Address address of the ERC-20 token corresponding to the deposit
function depositErc20(RecordOpening memory ro, address erc20Address) public nonReentrant {
alxiong marked this conversation as resolved.
Show resolved Hide resolved
require(isCapeAssetRegistered(ro.assetDef), "Asset definition not registered");
require(lookup(ro.assetDef) == erc20Address, "Wrong ERC20 address");

// We skip the sanity checks mentioned in the rust specification as they are optional.
if (pendingDeposits.length >= MAX_NUM_PENDING_DEPOSIT) {
Expand Down
85 changes: 43 additions & 42 deletions contracts/rust/src/cape/wrapping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ mod errors_when_calling_deposit_erc20 {
use std::sync::Arc;

use super::*;
use crate::assertion::EnsureMined;
use crate::deploy::{deploy_erc20_token, deploy_test_cape};
use crate::model::{erc20_asset_description, Erc20Code, EthereumAddr};
use crate::types as sol;
Expand All @@ -29,15 +30,16 @@ mod errors_when_calling_deposit_erc20 {
use jf_cap::keys::UserPubKey;
use jf_cap::structs::{AssetCode, AssetDefinition, AssetPolicy, FreezeFlag, RecordOpening};

enum WrongCallDepositErc20 {
enum Scenario {
AssetTypeNotRegistered,
SkipApproval,
PendingDepositsQueueIsFull,
WrongERC20Address,
}

async fn call_deposit_erc20_with_error_helper(
expected_error_message: &str,
wrong_call: WrongCallDepositErc20,
scenario: Scenario,
) -> Result<()> {
let cape_contract = deploy_test_cape().await;

Expand All @@ -54,20 +56,15 @@ mod errors_when_calling_deposit_erc20 {

let amount_u256 = U256::from(deposited_amount);

match wrong_call {
WrongCallDepositErc20::AssetTypeNotRegistered
| WrongCallDepositErc20::PendingDepositsQueueIsFull => {
erc20_token_contract
.approve(contract_address, amount_u256)
.send()
.await?
.await?;
}
WrongCallDepositErc20::SkipApproval => {}
if !(matches!(scenario, Scenario::SkipApproval)) {
erc20_token_contract
.approve(contract_address, amount_u256)
.send()
.await?
.await?
.ensure_mined();
};

// Call CAPE contract function

// Sponsor asset type
let rng = &mut ark_std::test_rng();
let erc20_code = Erc20Code(EthereumAddr(erc20_address.to_fixed_bytes()));
Expand All @@ -79,32 +76,26 @@ mod errors_when_calling_deposit_erc20 {
let asset_def = AssetDefinition::new(asset_code, AssetPolicy::rand_for_test(rng)).unwrap();
let asset_def_sol = asset_def.clone().generic_into::<sol::AssetDefinition>();

match wrong_call {
WrongCallDepositErc20::SkipApproval
| WrongCallDepositErc20::PendingDepositsQueueIsFull => {
TestCAPE::new(
cape_contract.address(),
Arc::new(owner_of_erc20_tokens_client.clone()),
)
.sponsor_cape_asset(erc20_address, asset_def_sol)
.send()
.await?
.await?;
}
WrongCallDepositErc20::AssetTypeNotRegistered => {}
if !(matches!(scenario, Scenario::AssetTypeNotRegistered)) {
TestCAPE::new(
cape_contract.address(),
Arc::new(owner_of_erc20_tokens_client.clone()),
)
.sponsor_cape_asset(erc20_address, asset_def_sol)
.send()
.await?
.await?
.ensure_mined();
}

match wrong_call {
WrongCallDepositErc20::PendingDepositsQueueIsFull => {
cape_contract
.fill_up_pending_deposits_queue()
.send()
.await?
.await?;
}
WrongCallDepositErc20::AssetTypeNotRegistered | WrongCallDepositErc20::SkipApproval => {
}
}
if matches!(scenario, Scenario::PendingDepositsQueueIsFull) {
cape_contract
.fill_up_pending_deposits_queue()
.send()
.await?
.await?
.ensure_mined();
};

// Build record opening
let ro = RecordOpening::new(
Expand All @@ -119,7 +110,11 @@ mod errors_when_calling_deposit_erc20 {
let call = cape_contract
.deposit_erc_20(
ro.clone().generic_into::<sol::RecordOpening>(),
erc20_address,
if matches!(scenario, Scenario::WrongERC20Address) {
Address::random()
} else {
erc20_address
},
)
.from(owner_of_erc20_tokens_client_address)
.call()
Expand All @@ -134,7 +129,7 @@ mod errors_when_calling_deposit_erc20 {
async fn the_asset_type_is_not_registered() -> Result<()> {
call_deposit_erc20_with_error_helper(
"Asset definition not registered",
WrongCallDepositErc20::AssetTypeNotRegistered,
Scenario::AssetTypeNotRegistered,
)
.await
}
Expand All @@ -143,7 +138,7 @@ mod errors_when_calling_deposit_erc20 {
async fn the_erc20_token_were_not_approved_before_calling_deposit_erc20() -> Result<()> {
call_deposit_erc20_with_error_helper(
"ERC20: transfer amount exceeds allowance",
WrongCallDepositErc20::SkipApproval,
Scenario::SkipApproval,
)
.await
}
Expand All @@ -152,10 +147,16 @@ mod errors_when_calling_deposit_erc20 {
async fn the_erc20_tok() -> Result<()> {
call_deposit_erc20_with_error_helper(
"Pending deposits queue is full",
WrongCallDepositErc20::PendingDepositsQueueIsFull,
Scenario::PendingDepositsQueueIsFull,
)
.await
}

#[tokio::test]
async fn erc20_address_mismatch_asset_definition_fails() -> Result<()> {
call_deposit_erc20_with_error_helper("Wrong ERC20 address", Scenario::WrongERC20Address)
.await
}
}

#[tokio::test]
Expand Down