Add selector collisions to the IERC20 lib

This commit is contained in:
Luke Parker 2025-01-23 08:22:41 -05:00
parent 7e53eff642
commit e922264ebf
No known key found for this signature in database
4 changed files with 47 additions and 4 deletions
processor/ethereum
erc20
router/contracts

View file

@ -18,3 +18,17 @@ interface IERC20 {
function approve(address spender, uint256 value) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
}
interface SeraiIERC20 {
function transferWithInInstruction01BB244A8A(
address to,
uint256 value,
bytes calldata inInstruction
) external returns (bool);
function transferFromWithInInstruction00081948E0(
address from,
address to,
uint256 value,
bytes calldata inInstruction
) external returns (bool);
}

View file

@ -28,8 +28,15 @@ mod abi {
alloy_sol_macro::sol!("contracts/IERC20.sol");
}
use abi::IERC20::{IERC20Calls, transferCall, transferFromCall};
use abi::SeraiIERC20::{
SeraiIERC20Calls, transferWithInInstruction01BB244A8ACall as transferWithInInstructionCall,
transferFromWithInInstruction00081948E0Call as transferFromWithInInstructionCall,
};
pub use abi::IERC20::Transfer;
#[cfg(test)]
mod tests;
/// A top-level ERC20 transfer
///
/// This does not include `token`, `to` fields. Those are assumed contextual to the creation of
@ -139,8 +146,18 @@ impl Erc20 {
}
// Read the data appended after
let encoded = call.abi_encode();
let data = transaction.inner.input().as_ref()[encoded.len() ..].to_vec();
let data = if let Ok(call) = SeraiIERC20Calls::abi_decode(transaction.inner.input(), true) {
match call {
SeraiIERC20Calls::transferWithInInstruction01BB244A8A(
transferWithInInstructionCall { inInstruction, .. },
) |
SeraiIERC20Calls::transferFromWithInInstruction00081948E0(
transferFromWithInInstructionCall { inInstruction, .. },
) => Vec::from(inInstruction),
}
} else {
vec![]
};
return Ok(Some(TopLevelTransfer {
id: LogIndex { block_hash: *block_hash, index_within_block: log_index },

View file

@ -0,0 +1,13 @@
use alloy_sol_types::SolCall;
#[test]
fn selector_collisions() {
assert_eq!(
crate::abi::IERC20::transferCall::SELECTOR,
crate::abi::SeraiIERC20::transferWithInInstruction01BB244A8ACall::SELECTOR
);
assert_eq!(
crate::abi::IERC20::transferFromCall::SELECTOR,
crate::abi::SeraiIERC20::transferFromWithInInstruction00081948E0Call::SELECTOR
);
}

View file

@ -29,8 +29,7 @@ contract Router is IRouterWithoutCollisions {
bytes32 constant ACCOUNT_WITHOUT_CODE_CODEHASH = keccak256("");
/// @dev The address in transient storage used for the reentrancy guard
bytes32 constant REENTRANCY_GUARD_SLOT =
bytes32(uint256(keccak256("ReentrancyGuard Router")) - 1);
bytes32 constant REENTRANCY_GUARD_SLOT = bytes32(uint256(keccak256("ReentrancyGuard Router")) - 1);
/**
* @dev The next nonce used to determine the address of contracts deployed with CREATE. This is