Skip to content

Commit

Permalink
Add safe_transfer_from_+ tests + fix eoa rejection tests (fix alice a…
Browse files Browse the repository at this point in the history
…ddress)
  • Loading branch information
0xNeshi committed Sep 23, 2024
1 parent b6ccccf commit c42aa9d
Show file tree
Hide file tree
Showing 4 changed files with 167 additions and 5 deletions.
41 changes: 41 additions & 0 deletions contracts/src/token/erc20/utils/safe_erc20.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,20 @@ sol_interface! {
/// Interface of the ERC-20 standard as defined in the ERC.
interface IERC20 {
/// Moves a `value` amount of tokens from the caller's account to `to`.
///
/// Returns a boolean value indicating whether the operation succeeded.
///
/// Emits a {Transfer} event.
function transfer(address to, uint256 amount) external returns (bool);

/// Moves a `value` amount of tokens from `from` to `to` using the
/// allowance mechanism. `value` is then deducted from the caller's
/// allowance.
///
/// Returns a boolean value indicating whether the operation succeeded.
///
/// Emits a {Transfer} event.
function transferFrom(address from, address to, uint256 amount) external returns (bool);
}
}

Expand Down Expand Up @@ -87,4 +98,34 @@ impl SafeErc20 {

Ok(())
}

/// Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
/// calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
pub fn safe_transfer_from(
&mut self,
token: Address,
from: Address,
to: Address,
value: U256,
) -> Result<(), Error> {
let erc20 = IERC20::new(token);
let call = Call::new_in(self);

match erc20.transfer_from(call, from, to, value) {
Ok(data) => {
if data && !Address::has_code(&token) {
return Err(Error::SafeErc20FailedOperation(
SafeErc20FailedOperation { token },
));
}
}
Err(_) => {
return Err(Error::SafeErc20FailedOperation(
SafeErc20FailedOperation { token },
))
}
}

Ok(())
}
}
1 change: 1 addition & 0 deletions examples/safe-erc20/tests/abi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ sol!(
#[sol(rpc)]
contract SafeErc20 {
function safeTransfer(address token, address to, uint256 value) external;
function safeTransferFrom(address token, address from, address to, uint256 value) external;

error SafeErc20FailedOperation(address token);
error SafeErc20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);
Expand Down
Loading

0 comments on commit c42aa9d

Please sign in to comment.