编译器
0.8.26+commit.8a97fa7a
文件 1 的 3:IETH.sol
pragma solidity ^0.8.19;
import {SafeTransferLib} from "../lib/solady/src/utils/SafeTransferLib.sol";
import {MetadataReaderLib} from "../lib/solady/src/utils/MetadataReaderLib.sol";
contract IETH {
using SafeTransferLib for address;
using MetadataReaderLib for address;
error Overflow();
error InvalidSwap();
error InvalidSyntax();
error InvalidCharacter();
error InsufficientSwap();
error InvalidSelector();
event NameSet(address token, string name);
event PairSet(address token0, address token1, address pair);
struct PackedUserOperation {
address sender;
uint256 nonce;
bytes initCode;
bytes callData;
bytes32 accountGasLimits;
uint256 preVerificationGas;
bytes32 gasFees;
bytes paymasterAndData;
bytes signature;
}
struct SwapInfo {
bool ETHIn;
bool ETHOut;
address tokenIn;
address tokenOut;
uint256 amountIn;
}
struct SwapLiq {
address pool;
uint256 liq;
}
struct StringPart {
uint256 start;
uint256 end;
}
enum Rule {
DISALLOWED,
VALID
}
address internal constant DAO = 0xDa000000000000d2885F108500803dfBAaB2f2aA;
address internal constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
address internal constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
address internal constant WBTC = 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599;
address internal constant USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;
address internal constant USDT = 0xdAC17F958D2ee523a2206206994597C13D831ec7;
address internal constant DAI = 0x6B175474E89094C44Da98b954EedeAC495271d0F;
address internal constant WSTETH = 0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0;
address internal constant RETH = 0xae78736Cd615f374D3085123A210448E74Fc6393;
address internal constant UNISWAP_V3_FACTORY = 0x1F98431c8aD98523631AE4a59f267346ea31F984;
bytes32 internal constant UNISWAP_V3_POOL_INIT_CODE_HASH =
0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54;
uint160 internal constant MIN_SQRT_RATIO_PLUS_ONE = 4295128740;
uint160 internal constant MAX_SQRT_RATIO_MINUS_ONE =
1461446703485210103287273052203988822378723970341;
IENSHelper internal constant ENS_REGISTRY =
IENSHelper(0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e);
IENSHelper internal constant ENS_WRAPPER =
IENSHelper(0xD4416b13d2b3a9aBae7AcD5D6C2BbDBE25686401);
bytes internal constant ASCII_MAP =
hex"2d00020101000a010700016101620163016401650166016701680169016a016b016c016d016e016f0170017101720173017401750176017701780179017a06001a010500";
INAMI internal nami;
mapping(string name => address) public addresses;
mapping(address addresses => string) public names;
mapping(address token0 => mapping(address token1 => address)) public pairs;
bytes1[] internal _idnamap;
constructor() payable {
unchecked {
for (uint256 i; i != ASCII_MAP.length; i += 2) {
bytes1 r = ASCII_MAP[i + 1];
for (uint8 j; j != uint8(ASCII_MAP[i]); ++j) {
_idnamap.push(r);
}
}
}
}
function previewCommand(string calldata intent)
public
view
virtual
returns (
address to,
uint256 amount,
uint256 minAmountOut,
address token,
bytes memory callData,
bytes memory executeCallData
)
{
bytes memory normalized = _lowercase(bytes(intent));
bytes32 action = _extraction(normalized);
if (action == "send" || action == "transfer" || action == "pay" || action == "grant") {
(bytes memory _to, bytes memory _amount, bytes memory _token) = _extractSend(normalized);
(to, amount, token, callData, executeCallData) = _previewSend(_to, _amount, _token);
} else if (
action == "swap" || action == "sell" || action == "exchange" || action == "stake"
) {
(
bytes memory amountIn,
bytes memory amountOutMin,
bytes memory tokenIn,
bytes memory tokenOut,
bytes memory receiver
) = _extractSwap(normalized);
address _receiver;
(amount, minAmountOut, token, to, _receiver) =
_previewSwap(amountIn, amountOutMin, tokenIn, tokenOut, receiver);
callData = abi.encodePacked(_receiver);
} else {
revert InvalidSyntax();
}
}
function _previewSend(bytes memory to, bytes memory amount, bytes memory token)
internal
view
virtual
returns (
address _to,
uint256 _amount,
address _token,
bytes memory callData,
bytes memory executeCallData
)
{
uint256 decimals;
(_token, decimals) = _returnTokenConstants(bytes32(token));
if (_token == address(0)) _token = addresses[string(token)];
bool isETH = _token == ETH;
(, _to,) = whatIsTheAddressOf(string(to));
_amount = _toUint(amount, decimals != 0 ? decimals : _token.readDecimals(), _token);
if (!isETH) callData = abi.encodeCall(IToken.transfer, (_to, _amount));
executeCallData =
abi.encodeCall(IExecutor.execute, (isETH ? _to : _token, isETH ? _amount : 0, callData));
}
function _previewSwap(
bytes memory amountIn,
bytes memory amountOutMin,
bytes memory tokenIn,
bytes memory tokenOut,
bytes memory receiver
)
internal
view
virtual
returns (
uint256 _amountIn,
uint256 _amountOut,
address _tokenIn,
address _tokenOut,
address _receiver
)
{
uint256 decimalsIn;
uint256 decimalsOut;
(_tokenIn, decimalsIn) = _returnTokenConstants(bytes32(tokenIn));
if (_tokenIn == address(0)) _tokenIn = addresses[string(tokenIn)];
(_tokenOut, decimalsOut) = _returnTokenConstants(bytes32(tokenOut));
if (_tokenOut == address(0)) _tokenOut = addresses[string(tokenOut)];
_amountIn =
_toUint(amountIn, decimalsIn != 0 ? decimalsIn : _tokenIn.readDecimals(), _tokenIn);
_amountOut = _toUint(
amountOutMin, decimalsOut != 0 ? decimalsOut : _tokenOut.readDecimals(), _tokenOut
);
if (receiver.length != 0) (, _receiver,) = whatIsTheAddressOf(string(receiver));
}
function checkUserOp(string calldata intent, PackedUserOperation calldata userOp)
public
view
virtual
returns (bool intentMatched)
{
(,,,,, bytes memory executeCallData) = previewCommand(intent);
if (executeCallData.length != userOp.callData.length) return false;
return keccak256(executeCallData) == keccak256(userOp.callData);
}
function _returnTokenConstants(bytes32 token)
internal
pure
virtual
returns (address _token, uint256 _decimals)
{
if (token == "eth" || token == "ether") return (ETH, 18);
if (token == "usdc") return (USDC, 6);
if (token == "usdt" || token == "tether") return (USDT, 6);
if (token == "dai") return (DAI, 18);
if (token == "weth") return (WETH, 18);
if (token == "wbtc" || token == "btc" || token == "bitcoin") return (WBTC, 8);
if (token == "steth" || token == "wsteth" || token == "lido") return (WSTETH, 18);
if (token == "reth") return (RETH, 18);
}
function _returnTokenAliasConstants(address token)
internal
pure
virtual
returns (string memory _token, uint256 _decimals)
{
if (token == USDC) return ("USDC", 6);
if (token == USDT) return ("USDT", 6);
if (token == DAI) return ("DAI", 18);
if (token == WETH) return ("WETH", 18);
if (token == WBTC) return ("WBTC", 8);
if (token == WSTETH) return ("WSTETH", 18);
if (token == RETH) return ("RETH", 18);
}
function _returnPoolConstants(address token0, address token1)
internal
pure
virtual
returns (address pool)
{
if (token0 == WSTETH && token1 == WETH) return 0x109830a1AAaD605BbF02a9dFA7B0B92EC2FB7dAa;
if (token0 == RETH && token1 == WETH) return 0x553e9C493678d8606d6a5ba284643dB2110Df823;
if (token0 == USDC && token1 == WETH) return 0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640;
if (token0 == WETH && token1 == USDT) return 0x11b815efB8f581194ae79006d24E0d814B7697F6;
if (token0 == DAI && token1 == WETH) return 0xC2e9F25Be6257c210d7Adf0D4Cd6E3E881ba25f8;
if (token0 == WBTC && token1 == WETH) return 0x4585FE77225b41b697C938B018E2Ac67Ac5a20c0;
}
function command(string calldata intent) public payable virtual {
bytes memory normalized = _lowercase(bytes(intent));
bytes32 action = _extraction(normalized);
if (action == "send" || action == "transfer" || action == "pay" || action == "grant") {
(bytes memory to, bytes memory amount, bytes memory token) = _extractSend(normalized);
send(string(to), string(amount), string(token));
} else if (
action == "swap" || action == "sell" || action == "exchange" || action == "stake"
) {
(
bytes memory amountIn,
bytes memory amountOutMin,
bytes memory tokenIn,
bytes memory tokenOut,
bytes memory receiver
) = _extractSwap(normalized);
swap(
string(amountIn),
string(amountOutMin),
string(tokenIn),
string(tokenOut),
string(receiver)
);
} else {
revert InvalidSyntax();
}
}
function command(string[] calldata intents) public payable virtual {
for (uint256 i; i != intents.length; ++i) {
command(intents[i]);
}
}
function send(string memory to, string memory amount, string memory token)
public
payable
virtual
{
(address _token, uint256 decimals) = _returnTokenConstants(bytes32(bytes(token)));
if (_token == address(0)) _token = addresses[token];
(, address _to,) = whatIsTheAddressOf(to);
uint256 _amount =
_toUint(bytes(amount), decimals != 0 ? decimals : _token.readDecimals(), _token);
if (_token == ETH) {
_to.safeTransferETH(_amount);
} else {
_token.safeTransferFrom(msg.sender, _to, _amount);
}
}
function swap(
string memory amountIn,
string memory amountOutMin,
string memory tokenIn,
string memory tokenOut,
string memory receiver
) public payable virtual {
SwapInfo memory info;
uint256 decimalsIn;
uint256 decimalsOut;
(info.tokenIn, decimalsIn) = _returnTokenConstants(bytes32(bytes(tokenIn)));
if (info.tokenIn == address(0)) info.tokenIn = addresses[tokenIn];
(info.tokenOut, decimalsOut) = _returnTokenConstants(bytes32(bytes(tokenOut)));
if (info.tokenOut == address(0)) info.tokenOut = addresses[tokenOut];
info.ETHIn = info.tokenIn == ETH;
if (info.ETHIn) info.tokenIn = WETH;
info.ETHOut = info.tokenOut == ETH;
if (info.ETHOut) info.tokenOut = WETH;
uint256 minOut;
if (bytes(amountOutMin).length != 0) {
minOut = _toUint(
bytes(amountOutMin),
decimalsOut != 0 ? decimalsOut : info.tokenOut.readDecimals(),
info.tokenOut
);
}
bool exactOut = bytes(amountIn).length == 0;
info.amountIn = exactOut
? minOut
: _toUint(
bytes(amountIn),
decimalsIn != 0 ? decimalsIn : info.tokenIn.readDecimals(),
info.tokenIn
);
if (info.amountIn >= 1 << 255) revert Overflow();
address _receiver;
if (bytes(receiver).length == 0) _receiver = msg.sender;
else (, _receiver,) = whatIsTheAddressOf(receiver);
(address pool, bool zeroForOne) = _computePoolAddress(info.tokenIn, info.tokenOut);
(int256 amount0, int256 amount1) = ISwapRouter(pool).swap(
!info.ETHOut ? _receiver : address(this),
zeroForOne,
!exactOut ? int256(info.amountIn) : -int256(info.amountIn),
zeroForOne ? MIN_SQRT_RATIO_PLUS_ONE : MAX_SQRT_RATIO_MINUS_ONE,
abi.encodePacked(
info.ETHIn, info.ETHOut, msg.sender, info.tokenIn, info.tokenOut, _receiver
)
);
if (minOut != 0) {
if (uint256(-(zeroForOne ? amount1 : amount0)) < minOut) revert InsufficientSwap();
}
}
fallback() external payable virtual {
int256 amount0Delta;
int256 amount1Delta;
bool ETHIn;
bool ETHOut;
address payer;
address tokenIn;
address tokenOut;
address receiver;
assembly ("memory-safe") {
amount0Delta := calldataload(0x4)
amount1Delta := calldataload(0x24)
ETHIn := byte(0, calldataload(0x84))
ETHOut := byte(0, calldataload(add(0x84, 1)))
payer := shr(96, calldataload(add(0x84, 2)))
tokenIn := shr(96, calldataload(add(0x84, 22)))
tokenOut := shr(96, calldataload(add(0x84, 42)))
receiver := shr(96, calldataload(add(0x84, 62)))
}
if (amount0Delta <= 0 && amount1Delta <= 0) revert InvalidSwap();
(address pool, bool zeroForOne) = _computePoolAddress(tokenIn, tokenOut);
assembly ("memory-safe") {
if iszero(eq(caller(), pool)) { revert(codesize(), codesize()) }
}
if (ETHIn) {
_wrapETH(uint256(zeroForOne ? amount0Delta : amount1Delta));
} else {
tokenIn.safeTransferFrom(payer, pool, uint256(zeroForOne ? amount0Delta : amount1Delta));
}
if (ETHOut) {
uint256 amount = uint256(-(zeroForOne ? amount1Delta : amount0Delta));
_unwrapETH(amount);
receiver.safeTransferETH(amount);
}
}
function _computePoolAddress(address tokenA, address tokenB)
internal
view
virtual
returns (address pool, bool zeroForOne)
{
if (tokenA < tokenB) zeroForOne = true;
else (tokenA, tokenB) = (tokenB, tokenA);
pool = _returnPoolConstants(tokenA, tokenB);
if (pool == address(0)) {
pool = pairs[tokenA][tokenB];
if (pool == address(0)) {
address pool100 = _computePairHash(tokenA, tokenB, 100);
address pool500 = _computePairHash(tokenA, tokenB, 500);
address pool3000 = _computePairHash(tokenA, tokenB, 3000);
address pool10000 = _computePairHash(tokenA, tokenB, 10000);
SwapLiq memory topPool;
uint256 liq;
if (pool100.code.length != 0) {
liq = _balanceOf(tokenA, pool100);
topPool = SwapLiq(pool100, liq);
}
if (pool500.code.length != 0) {
liq = _balanceOf(tokenA, pool500);
if (liq > topPool.liq) {
topPool = SwapLiq(pool500, liq);
}
}
if (pool3000.code.length != 0) {
liq = _balanceOf(tokenA, pool3000);
if (liq > topPool.liq) {
topPool = SwapLiq(pool3000, liq);
}
}
if (pool10000.code.length != 0) {
liq = _balanceOf(tokenA, pool10000);
if (liq > topPool.liq) {
topPool = SwapLiq(pool10000, liq);
}
}
pool = topPool.pool;
}
}
}
function _computePairHash(address token0, address token1, uint24 fee)
internal
pure
virtual
returns (address pool)
{
bytes32 salt = _hash(token0, token1, fee);
assembly ("memory-safe") {
mstore8(0x00, 0xff)
mstore(0x35, UNISWAP_V3_POOL_INIT_CODE_HASH)
mstore(0x01, shl(96, UNISWAP_V3_FACTORY))
mstore(0x15, salt)
pool := keccak256(0x00, 0x55)
mstore(0x35, 0)
}
}
function _hash(address value0, address value1, uint24 value2)
internal
pure
virtual
returns (bytes32 result)
{
assembly ("memory-safe") {
let m := mload(0x40)
mstore(m, value0)
mstore(add(m, 0x20), value1)
mstore(add(m, 0x40), value2)
result := keccak256(m, 0x60)
}
}
function _wrapETH(uint256 amount) internal virtual {
assembly ("memory-safe") {
pop(call(gas(), WETH, amount, codesize(), 0x00, codesize(), 0x00))
mstore(0x14, caller())
mstore(0x34, amount)
mstore(0x00, 0xa9059cbb000000000000000000000000)
pop(call(gas(), WETH, 0, 0x10, 0x44, codesize(), 0x00))
mstore(0x34, 0)
}
}
function _unwrapETH(uint256 amount) internal virtual {
assembly ("memory-safe") {
mstore(0x00, 0x2e1a7d4d)
mstore(0x20, amount)
pop(call(gas(), WETH, 0, 0x1c, 0x24, codesize(), 0x00))
}
}
function _balanceOf(address token, address account)
internal
view
virtual
returns (uint256 amount)
{
assembly ("memory-safe") {
mstore(0x00, 0x70a08231000000000000000000000000)
mstore(0x14, account)
pop(staticcall(gas(), token, 0x10, 0x24, 0x20, 0x20))
amount := mload(0x20)
}
}
receive() external payable virtual {
assembly ("memory-safe") {
if iszero(eq(caller(), WETH)) { revert(codesize(), codesize()) }
}
}
function translateCommand(bytes calldata callData)
public
pure
virtual
returns (string memory intent)
{
return string(callData[4:]);
}
function translateExecute(bytes calldata callData)
public
view
virtual
returns (string memory intent)
{
unchecked {
(address target, uint256 value) = abi.decode(callData[4:68], (address, uint256));
if (value != 0) {
return string(
abi.encodePacked(
"send ",
_convertWeiToString(value, 18),
" ETH to 0x",
_toAsciiString(target)
)
);
}
if (
bytes4(callData[132:136]) != IToken.transfer.selector
&& bytes4(callData[132:136]) != IToken.approve.selector
) revert InvalidSelector();
bool transfer = bytes4(callData[132:136]) == IToken.transfer.selector;
(string memory token, uint256 decimals) = _returnTokenAliasConstants(target);
if (bytes(token).length == 0) token = names[target];
if (decimals == 0) decimals = target.readDecimals();
(target, value) = abi.decode(callData[136:], (address, uint256));
return string(
abi.encodePacked(
transfer ? "send " : "approve ",
_convertWeiToString(value, decimals),
" ",
token,
" to 0x",
_toAsciiString(target)
)
);
}
}
function translateUserOp(PackedUserOperation calldata userOp)
public
view
virtual
returns (string memory intent)
{
return bytes4(userOp.callData) == IExecutor.execute.selector
? translateExecute(userOp.callData)
: translateCommand(userOp.callData);
}
function whatIsTheAddressOf(string memory name)
public
view
virtual
returns (address owner, address receiver, bytes32 node)
{
node = _namehash(string(abi.encodePacked(name, ".eth")));
owner = ENS_REGISTRY.owner(node);
if (IENSHelper(owner) == ENS_WRAPPER) owner = ENS_WRAPPER.ownerOf(uint256(node));
receiver = IENSHelper(ENS_REGISTRY.resolver(node)).addr(node);
}
function _namehash(string memory domain) internal view virtual returns (bytes32 node) {
uint256 i = bytes(domain).length;
uint256 lastDot = i;
unchecked {
for (; i != 0; --i) {
bytes1 c = bytes(domain)[i - 1];
if (c == ".") {
node = keccak256(abi.encodePacked(node, _labelhash(domain, i, lastDot)));
lastDot = i - 1;
continue;
}
require(c < 0x80);
bytes1 r = _idnamap[uint8(c)];
require(uint8(r) != uint8(Rule.DISALLOWED));
if (uint8(r) > 1) {
bytes(domain)[i - 1] = r;
}
}
}
return keccak256(abi.encodePacked(node, _labelhash(domain, i, lastDot)));
}
function _labelhash(string memory domain, uint256 start, uint256 end)
internal
pure
virtual
returns (bytes32 hash)
{
assembly ("memory-safe") {
hash := keccak256(add(add(domain, 0x20), start), sub(end, start))
}
}
function setName(address token, string calldata name) public payable virtual {
assembly ("memory-safe") {
if iszero(eq(caller(), DAO)) { revert(codesize(), codesize()) }
}
string memory normalized = string(_lowercase(bytes(name)));
names[token] = normalized;
emit NameSet(addresses[normalized] = token, normalized);
}
function setName(address token) public payable virtual {
string memory normalizedName = string(_lowercase(bytes(token.readName())));
string memory normalizedSymbol = string(_lowercase(bytes(token.readSymbol())));
names[token] = normalizedSymbol;
emit NameSet(addresses[normalizedName] = token, normalizedName);
emit NameSet(addresses[normalizedSymbol] = token, normalizedSymbol);
}
function setPair(address tokenA, address tokenB, address pair) public payable virtual {
assembly ("memory-safe") {
if iszero(eq(caller(), DAO)) { revert(codesize(), codesize()) }
}
if (tokenB < tokenA) (tokenA, tokenB) = (tokenB, tokenA);
emit PairSet(tokenA, tokenB, pairs[tokenA][tokenB] = pair);
}
function setNAMI(INAMI NAMI) public payable virtual {
assembly ("memory-safe") {
if iszero(eq(caller(), DAO)) { revert(codesize(), codesize()) }
}
nami = NAMI;
}
function _lowercase(bytes memory subject) internal pure virtual returns (bytes memory result) {
assembly ("memory-safe") {
let len := mload(subject)
result := add(mload(0x40), 0x20)
subject := add(subject, 1)
let flags := shl(add(70, shl(5, 0)), 0x3ffffff)
let w := not(0)
for { let o := len } 1 {} {
o := add(o, w)
let b := and(0xff, mload(add(subject, o)))
mstore8(add(result, o), xor(b, and(shr(b, flags), 0x20)))
if iszero(o) { break }
}
result := mload(0x40)
mstore(result, len)
let last := add(add(result, 0x20), len)
mstore(last, 0)
mstore(0x40, add(last, 0x20))
}
}
function _extraction(bytes memory normalizedIntent)
internal
pure
virtual
returns (bytes32 result)
{
assembly ("memory-safe") {
let str := add(normalizedIntent, 0x20)
result := mload(str)
let spaceIndex := 32
for { let i := 0 } lt(i, 32) { i := add(i, 1) } {
let char := byte(i, result)
if or(eq(char, 0x20), eq(char, 0)) {
spaceIndex := i
break
}
}
let mask := shl(mul(8, sub(32, spaceIndex)), not(0))
result := and(result, mask)
}
}
function _extractSend(bytes memory normalizedIntent)
internal
pure
virtual
returns (bytes memory to, bytes memory amount, bytes memory token)
{
StringPart[] memory parts = _split(normalizedIntent, " ");
if (parts.length == 4) {
return (
_getPart(normalizedIntent, parts[1]),
_getPart(normalizedIntent, parts[2]),
_getPart(normalizedIntent, parts[3])
);
}
if (parts.length == 5) {
return (
_getPart(normalizedIntent, parts[4]),
_getPart(normalizedIntent, parts[1]),
_getPart(normalizedIntent, parts[2])
);
} else {
revert InvalidSyntax();
}
}
function _extractSwap(bytes memory normalizedIntent)
internal
pure
virtual
returns (
bytes memory amountIn,
bytes memory amountOutMin,
bytes memory tokenIn,
bytes memory tokenOut,
bytes memory receiver
)
{
StringPart[] memory parts = _split(normalizedIntent, " ");
bool isNumber;
if (parts.length == 5) {
isNumber = _isNumber(_getPart(normalizedIntent, parts[1]));
if (isNumber) {
return (
_getPart(normalizedIntent, parts[1]),
"",
_getPart(normalizedIntent, parts[2]),
_getPart(normalizedIntent, parts[4]),
""
);
} else {
return (
"",
_getPart(normalizedIntent, parts[3]),
_getPart(normalizedIntent, parts[1]),
_getPart(normalizedIntent, parts[4]),
""
);
}
} else if (parts.length == 6) {
return (
_getPart(normalizedIntent, parts[1]),
_getPart(normalizedIntent, parts[4]),
_getPart(normalizedIntent, parts[2]),
_getPart(normalizedIntent, parts[5]),
""
);
} else if (parts.length == 7) {
isNumber = _isNumber(_getPart(normalizedIntent, parts[1]));
if (isNumber) {
return (
_getPart(normalizedIntent, parts[1]),
"",
_getPart(normalizedIntent, parts[2]),
_getPart(normalizedIntent, parts[4]),
_getPart(normalizedIntent, parts[6])
);
} else {
return (
"",
_getPart(normalizedIntent, parts[3]),
_getPart(normalizedIntent, parts[1]),
_getPart(normalizedIntent, parts[4]),
_getPart(normalizedIntent, parts[6])
);
}
} else if (parts.length == 8) {
return (
_getPart(normalizedIntent, parts[1]),
_getPart(normalizedIntent, parts[4]),
_getPart(normalizedIntent, parts[2]),
_getPart(normalizedIntent, parts[5]),
_getPart(normalizedIntent, parts[7])
);
} else {
revert InvalidSyntax();
}
}
function _isNumber(bytes memory s) internal pure virtual returns (bool) {
if (bytes32(s) == "all") return true;
return (s[0] >= 0x30 && s[0] <= 0x39);
}
function _split(bytes memory base, bytes1 delimiter)
internal
pure
virtual
returns (StringPart[] memory parts)
{
unchecked {
uint256 len = base.length;
uint256 count = 1;
for (uint256 i; i != len; ++i) {
if (base[i] == delimiter) {
++count;
}
}
parts = new StringPart[](count);
uint256 partIndex;
uint256 start;
for (uint256 i; i != len; ++i) {
if (base[i] == delimiter) {
parts[partIndex++] = StringPart(start, i);
start = i + 1;
}
}
parts[partIndex] = StringPart(start, len);
}
}
function _getPart(bytes memory base, StringPart memory part)
internal
pure
virtual
returns (bytes memory)
{
unchecked {
bytes memory result = new bytes(part.end - part.start);
for (uint256 i; i != result.length; ++i) {
result[i] = base[part.start + i];
}
return result;
}
}
function _toUint(bytes memory s, uint256 decimals, address token)
internal
view
virtual
returns (uint256 result)
{
unchecked {
bytes32 sBytes32 = bytes32(s);
if (sBytes32 == bytes32("all") || sBytes32 == bytes32("100%")) {
return token == ETH ? msg.sender.balance + msg.value : _balanceOf(token, msg.sender);
}
uint256 len = s.length;
bool hasDecimal;
uint256 decimalPlaces;
bool isPercentage;
for (uint256 i; i < len; ++i) {
bytes1 c = s[i];
if (c >= 0x30 && c <= 0x39) {
result = result * 10 + uint8(c) - 48;
if (hasDecimal) {
if (++decimalPlaces > decimals) break;
}
} else if (c == 0x2E && !hasDecimal) {
hasDecimal = true;
} else if (c == 0x25 && i == len - 1) {
isPercentage = true;
} else if (c != 0x20) {
revert InvalidCharacter();
}
}
if (!hasDecimal) {
result *= 10 ** decimals;
} else if (decimalPlaces < decimals) {
result *= 10 ** (decimals - decimalPlaces);
}
if (isPercentage) {
uint256 balance =
token == ETH ? msg.sender.balance + msg.value : _balanceOf(token, msg.sender);
result = (balance * result) / (100 * 10 ** decimals);
}
}
}
function _toAddress(bytes memory s) internal pure virtual returns (address addr) {
unchecked {
if (s.length != 42) revert InvalidSyntax();
uint256 result;
for (uint256 i = 2; i != 42; ++i) {
result *= 16;
uint8 b = uint8(s[i]);
if (b >= 48 && b <= 57) {
result += b - 48;
} else if (b >= 65 && b <= 70) {
result += b - 55;
} else if (b >= 97 && b <= 102) {
result += b - 87;
} else {
revert InvalidSyntax();
}
}
return address(uint160(result));
}
}
function _toAsciiString(address x) internal pure virtual returns (string memory) {
unchecked {
bytes memory s = new bytes(40);
for (uint256 i; i != 20; ++i) {
bytes1 b = bytes1(uint8(uint256(uint160(x)) / (2 ** (8 * (19 - i)))));
bytes1 hi = bytes1(uint8(b) / 16);
bytes1 lo = bytes1(uint8(b) - 16 * uint8(hi));
s[2 * i] = _char(hi);
s[2 * i + 1] = _char(lo);
}
return string(s);
}
}
function _char(bytes1 b) internal pure virtual returns (bytes1 c) {
unchecked {
uint8 n = uint8(b) & 0xf;
c = bytes1(n + (n < 10 ? 0x30 : 0x57));
}
}
function _convertWeiToString(uint256 weiAmount, uint256 decimals)
internal
pure
virtual
returns (string memory)
{
unchecked {
uint256 scalingFactor = 10 ** decimals;
string memory wholeNumberStr = _toString(weiAmount / scalingFactor);
string memory decimalPartStr = _toString(weiAmount % scalingFactor);
while (bytes(decimalPartStr).length != decimals) {
decimalPartStr = string(abi.encodePacked("0", decimalPartStr));
}
decimalPartStr = _removeTrailingZeros(bytes(decimalPartStr));
if (bytes(decimalPartStr).length == 0) {
return wholeNumberStr;
}
return string(abi.encodePacked(wholeNumberStr, ".", decimalPartStr));
}
}
function _removeTrailingZeros(bytes memory str) internal pure virtual returns (string memory) {
unchecked {
uint256 len = str.length;
uint256 end = len;
while (end != 0 && str[end - 1] == 0x30) {
--end;
}
if (end == len) {
return string(str);
}
bytes memory trimmedBytes = new bytes(end);
for (uint256 i; i != end; ++i) {
trimmedBytes[i] = str[i];
}
return string(trimmedBytes);
}
}
function _toString(uint256 value) internal pure virtual returns (string memory str) {
assembly ("memory-safe") {
str := add(mload(0x40), 0x80)
mstore(0x40, add(str, 0x20))
mstore(str, 0)
let end := str
let w := not(0)
for { let temp := value } 1 {} {
str := add(str, w)
mstore8(str, add(48, mod(temp, 10)))
temp := div(temp, 10)
if iszero(temp) { break }
}
let len := sub(end, str)
str := sub(str, 0x20)
mstore(str, len)
}
}
}
interface IENSHelper {
function addr(bytes32) external view returns (address);
function owner(bytes32) external view returns (address);
function ownerOf(uint256) external view returns (address);
function resolver(bytes32) external view returns (address);
}
interface IToken {
function approve(address, uint256) external returns (bool);
function transfer(address, uint256) external returns (bool);
}
interface IExecutor {
function execute(address, uint256, bytes calldata) external payable returns (bytes memory);
}
interface INAMI {
function whatIsTheAddressOf(string calldata)
external
view
returns (address, address, bytes32);
}
interface ISwapRouter {
function swap(address, bool, int256, uint160, bytes calldata)
external
returns (int256, int256);
}
文件 2 的 3:MetadataReaderLib.sol
pragma solidity ^0.8.4;
library MetadataReaderLib {
uint256 internal constant GAS_STIPEND_NO_GRIEF = 100000;
uint256 internal constant STRING_LIMIT_DEFAULT = 1000;
function readName(address target) internal view returns (string memory) {
return _string(target, _ptr(0x06fdde03), STRING_LIMIT_DEFAULT, GAS_STIPEND_NO_GRIEF);
}
function readName(address target, uint256 limit) internal view returns (string memory) {
return _string(target, _ptr(0x06fdde03), limit, GAS_STIPEND_NO_GRIEF);
}
function readName(address target, uint256 limit, uint256 gasStipend)
internal
view
returns (string memory)
{
return _string(target, _ptr(0x06fdde03), limit, gasStipend);
}
function readSymbol(address target) internal view returns (string memory) {
return _string(target, _ptr(0x95d89b41), STRING_LIMIT_DEFAULT, GAS_STIPEND_NO_GRIEF);
}
function readSymbol(address target, uint256 limit) internal view returns (string memory) {
return _string(target, _ptr(0x95d89b41), limit, GAS_STIPEND_NO_GRIEF);
}
function readSymbol(address target, uint256 limit, uint256 gasStipend)
internal
view
returns (string memory)
{
return _string(target, _ptr(0x95d89b41), limit, gasStipend);
}
function readString(address target, bytes memory data) internal view returns (string memory) {
return _string(target, _ptr(data), STRING_LIMIT_DEFAULT, GAS_STIPEND_NO_GRIEF);
}
function readString(address target, bytes memory data, uint256 limit)
internal
view
returns (string memory)
{
return _string(target, _ptr(data), limit, GAS_STIPEND_NO_GRIEF);
}
function readString(address target, bytes memory data, uint256 limit, uint256 gasStipend)
internal
view
returns (string memory)
{
return _string(target, _ptr(data), limit, gasStipend);
}
function readDecimals(address target) internal view returns (uint8) {
return uint8(_uint(target, _ptr(0x313ce567), GAS_STIPEND_NO_GRIEF));
}
function readDecimals(address target, uint256 gasStipend) internal view returns (uint8) {
return uint8(_uint(target, _ptr(0x313ce567), gasStipend));
}
function readUint(address target, bytes memory data) internal view returns (uint256) {
return _uint(target, _ptr(data), GAS_STIPEND_NO_GRIEF);
}
function readUint(address target, bytes memory data, uint256 gasStipend)
internal
view
returns (uint256)
{
return _uint(target, _ptr(data), gasStipend);
}
function _string(address target, bytes32 ptr, uint256 limit, uint256 gasStipend)
private
view
returns (string memory result)
{
assembly {
function min(x_, y_) -> _z {
_z := xor(x_, mul(xor(x_, y_), lt(y_, x_)))
}
for {} staticcall(gasStipend, target, add(ptr, 0x20), mload(ptr), 0x00, 0x20) {} {
let m := mload(0x40)
let s := add(0x20, m)
if iszero(lt(returndatasize(), 0x40)) {
let o := mload(0x00)
if iszero(gt(o, sub(returndatasize(), 0x20))) {
returndatacopy(m, o, 0x20)
if iszero(gt(mload(m), sub(returndatasize(), add(o, 0x20)))) {
let n := min(mload(m), limit)
mstore(m, n)
returndatacopy(s, add(o, 0x20), n)
mstore(add(s, n), 0)
mstore(0x40, add(0x20, add(s, n)))
result := m
break
}
}
}
let n := min(returndatasize(), limit)
returndatacopy(s, 0, n)
mstore8(add(s, n), 0)
let i := s
for {} byte(0, mload(i)) { i := add(i, 1) } {}
mstore(m, sub(i, s))
mstore(i, 0)
mstore(0x40, add(0x20, i))
result := m
break
}
}
}
function _uint(address target, bytes32 ptr, uint256 gasStipend)
private
view
returns (uint256 result)
{
assembly {
result :=
mul(
mload(0x20),
and(
gt(returndatasize(), 0x1f),
staticcall(gasStipend, target, add(ptr, 0x20), mload(ptr), 0x20, 0x20)
)
)
}
}
function _ptr(uint256 s) private pure returns (bytes32 result) {
assembly {
mstore(0x04, s)
mstore(result, 4)
}
}
function _ptr(bytes memory data) private pure returns (bytes32 result) {
assembly {
result := data
}
}
}
文件 3 的 3:SafeTransferLib.sol
pragma solidity ^0.8.4;
library SafeTransferLib {
error ETHTransferFailed();
error TransferFromFailed();
error TransferFailed();
error ApproveFailed();
error Permit2Failed();
error Permit2AmountOverflow();
uint256 internal constant GAS_STIPEND_NO_STORAGE_WRITES = 2300;
uint256 internal constant GAS_STIPEND_NO_GRIEF = 100000;
bytes32 internal constant DAI_DOMAIN_SEPARATOR =
0xdbb8cf42e1ecb028be3f3dbc922e1d878b963f411dc388ced501601c60f7c6f7;
address internal constant WETH9 = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
address internal constant PERMIT2 = 0x000000000022D473030F116dDEE9F6B43aC78BA3;
function safeTransferETH(address to, uint256 amount) internal {
assembly {
if iszero(call(gas(), to, amount, codesize(), 0x00, codesize(), 0x00)) {
mstore(0x00, 0xb12d13eb)
revert(0x1c, 0x04)
}
}
}
function safeTransferAllETH(address to) internal {
assembly {
if iszero(call(gas(), to, selfbalance(), codesize(), 0x00, codesize(), 0x00)) {
mstore(0x00, 0xb12d13eb)
revert(0x1c, 0x04)
}
}
}
function forceSafeTransferETH(address to, uint256 amount, uint256 gasStipend) internal {
assembly {
if lt(selfbalance(), amount) {
mstore(0x00, 0xb12d13eb)
revert(0x1c, 0x04)
}
if iszero(call(gasStipend, to, amount, codesize(), 0x00, codesize(), 0x00)) {
mstore(0x00, to)
mstore8(0x0b, 0x73)
mstore8(0x20, 0xff)
if iszero(create(amount, 0x0b, 0x16)) { revert(codesize(), codesize()) }
}
}
}
function forceSafeTransferAllETH(address to, uint256 gasStipend) internal {
assembly {
if iszero(call(gasStipend, to, selfbalance(), codesize(), 0x00, codesize(), 0x00)) {
mstore(0x00, to)
mstore8(0x0b, 0x73)
mstore8(0x20, 0xff)
if iszero(create(selfbalance(), 0x0b, 0x16)) { revert(codesize(), codesize()) }
}
}
}
function forceSafeTransferETH(address to, uint256 amount) internal {
assembly {
if lt(selfbalance(), amount) {
mstore(0x00, 0xb12d13eb)
revert(0x1c, 0x04)
}
if iszero(call(GAS_STIPEND_NO_GRIEF, to, amount, codesize(), 0x00, codesize(), 0x00)) {
mstore(0x00, to)
mstore8(0x0b, 0x73)
mstore8(0x20, 0xff)
if iszero(create(amount, 0x0b, 0x16)) { revert(codesize(), codesize()) }
}
}
}
function forceSafeTransferAllETH(address to) internal {
assembly {
if iszero(call(GAS_STIPEND_NO_GRIEF, to, selfbalance(), codesize(), 0x00, codesize(), 0x00)) {
mstore(0x00, to)
mstore8(0x0b, 0x73)
mstore8(0x20, 0xff)
if iszero(create(selfbalance(), 0x0b, 0x16)) { revert(codesize(), codesize()) }
}
}
}
function trySafeTransferETH(address to, uint256 amount, uint256 gasStipend)
internal
returns (bool success)
{
assembly {
success := call(gasStipend, to, amount, codesize(), 0x00, codesize(), 0x00)
}
}
function trySafeTransferAllETH(address to, uint256 gasStipend)
internal
returns (bool success)
{
assembly {
success := call(gasStipend, to, selfbalance(), codesize(), 0x00, codesize(), 0x00)
}
}
function safeTransferFrom(address token, address from, address to, uint256 amount) internal {
assembly {
let m := mload(0x40)
mstore(0x60, amount)
mstore(0x40, to)
mstore(0x2c, shl(96, from))
mstore(0x0c, 0x23b872dd000000000000000000000000)
if iszero(
and(
or(eq(mload(0x00), 1), iszero(returndatasize())),
call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)
)
) {
mstore(0x00, 0x7939f424)
revert(0x1c, 0x04)
}
mstore(0x60, 0)
mstore(0x40, m)
}
}
function trySafeTransferFrom(address token, address from, address to, uint256 amount)
internal
returns (bool success)
{
assembly {
let m := mload(0x40)
mstore(0x60, amount)
mstore(0x40, to)
mstore(0x2c, shl(96, from))
mstore(0x0c, 0x23b872dd000000000000000000000000)
success :=
and(
or(eq(mload(0x00), 1), iszero(returndatasize())),
call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)
)
mstore(0x60, 0)
mstore(0x40, m)
}
}
function safeTransferAllFrom(address token, address from, address to)
internal
returns (uint256 amount)
{
assembly {
let m := mload(0x40)
mstore(0x40, to)
mstore(0x2c, shl(96, from))
mstore(0x0c, 0x70a08231000000000000000000000000)
if iszero(
and(
gt(returndatasize(), 0x1f),
staticcall(gas(), token, 0x1c, 0x24, 0x60, 0x20)
)
) {
mstore(0x00, 0x7939f424)
revert(0x1c, 0x04)
}
mstore(0x00, 0x23b872dd)
amount := mload(0x60)
if iszero(
and(
or(eq(mload(0x00), 1), iszero(returndatasize())),
call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)
)
) {
mstore(0x00, 0x7939f424)
revert(0x1c, 0x04)
}
mstore(0x60, 0)
mstore(0x40, m)
}
}
function safeTransfer(address token, address to, uint256 amount) internal {
assembly {
mstore(0x14, to)
mstore(0x34, amount)
mstore(0x00, 0xa9059cbb000000000000000000000000)
if iszero(
and(
or(eq(mload(0x00), 1), iszero(returndatasize())),
call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
)
) {
mstore(0x00, 0x90b8ec18)
revert(0x1c, 0x04)
}
mstore(0x34, 0)
}
}
function safeTransferAll(address token, address to) internal returns (uint256 amount) {
assembly {
mstore(0x00, 0x70a08231)
mstore(0x20, address())
if iszero(
and(
gt(returndatasize(), 0x1f),
staticcall(gas(), token, 0x1c, 0x24, 0x34, 0x20)
)
) {
mstore(0x00, 0x90b8ec18)
revert(0x1c, 0x04)
}
mstore(0x14, to)
amount := mload(0x34)
mstore(0x00, 0xa9059cbb000000000000000000000000)
if iszero(
and(
or(eq(mload(0x00), 1), iszero(returndatasize())),
call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
)
) {
mstore(0x00, 0x90b8ec18)
revert(0x1c, 0x04)
}
mstore(0x34, 0)
}
}
function safeApprove(address token, address to, uint256 amount) internal {
assembly {
mstore(0x14, to)
mstore(0x34, amount)
mstore(0x00, 0x095ea7b3000000000000000000000000)
if iszero(
and(
or(eq(mload(0x00), 1), iszero(returndatasize())),
call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
)
) {
mstore(0x00, 0x3e3f8f73)
revert(0x1c, 0x04)
}
mstore(0x34, 0)
}
}
function safeApproveWithRetry(address token, address to, uint256 amount) internal {
assembly {
mstore(0x14, to)
mstore(0x34, amount)
mstore(0x00, 0x095ea7b3000000000000000000000000)
if iszero(
and(
or(eq(mload(0x00), 1), iszero(returndatasize())),
call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
)
) {
mstore(0x34, 0)
mstore(0x00, 0x095ea7b3000000000000000000000000)
pop(call(gas(), token, 0, 0x10, 0x44, codesize(), 0x00))
mstore(0x34, amount)
if iszero(
and(
or(eq(mload(0x00), 1), iszero(returndatasize())),
call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
)
) {
mstore(0x00, 0x3e3f8f73)
revert(0x1c, 0x04)
}
}
mstore(0x34, 0)
}
}
function balanceOf(address token, address account) internal view returns (uint256 amount) {
assembly {
mstore(0x14, account)
mstore(0x00, 0x70a08231000000000000000000000000)
amount :=
mul(
mload(0x20),
and(
gt(returndatasize(), 0x1f),
staticcall(gas(), token, 0x10, 0x24, 0x20, 0x20)
)
)
}
}
function safeTransferFrom2(address token, address from, address to, uint256 amount) internal {
if (!trySafeTransferFrom(token, from, to, amount)) {
permit2TransferFrom(token, from, to, amount);
}
}
function permit2TransferFrom(address token, address from, address to, uint256 amount)
internal
{
assembly {
let m := mload(0x40)
mstore(add(m, 0x74), shr(96, shl(96, token)))
mstore(add(m, 0x54), amount)
mstore(add(m, 0x34), to)
mstore(add(m, 0x20), shl(96, from))
mstore(m, 0x36c78516000000000000000000000000)
let p := PERMIT2
let exists := eq(chainid(), 1)
if iszero(exists) { exists := iszero(iszero(extcodesize(p))) }
if iszero(and(call(gas(), p, 0, add(m, 0x10), 0x84, codesize(), 0x00), exists)) {
mstore(0x00, 0x7939f4248757f0fd)
revert(add(0x18, shl(2, iszero(iszero(shr(160, amount))))), 0x04)
}
}
}
function permit2(
address token,
address owner,
address spender,
uint256 amount,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
bool success;
assembly {
for {} shl(96, xor(token, WETH9)) {} {
mstore(0x00, 0x3644e515)
if iszero(
and(
lt(iszero(mload(0x00)), eq(returndatasize(), 0x20)),
staticcall(5000, token, 0x1c, 0x04, 0x00, 0x20)
)
) { break }
let m := mload(0x40)
mstore(add(m, 0x34), spender)
mstore(add(m, 0x20), shl(96, owner))
mstore(add(m, 0x74), deadline)
if eq(mload(0x00), DAI_DOMAIN_SEPARATOR) {
mstore(0x14, owner)
mstore(0x00, 0x7ecebe00000000000000000000000000)
mstore(add(m, 0x94), staticcall(gas(), token, 0x10, 0x24, add(m, 0x54), 0x20))
mstore(m, 0x8fcbaf0c000000000000000000000000)
mstore(add(m, 0xb4), and(0xff, v))
mstore(add(m, 0xd4), r)
mstore(add(m, 0xf4), s)
success := call(gas(), token, 0, add(m, 0x10), 0x104, codesize(), 0x00)
break
}
mstore(m, 0xd505accf000000000000000000000000)
mstore(add(m, 0x54), amount)
mstore(add(m, 0x94), and(0xff, v))
mstore(add(m, 0xb4), r)
mstore(add(m, 0xd4), s)
success := call(gas(), token, 0, add(m, 0x10), 0xe4, codesize(), 0x00)
break
}
}
if (!success) simplePermit2(token, owner, spender, amount, deadline, v, r, s);
}
function simplePermit2(
address token,
address owner,
address spender,
uint256 amount,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
assembly {
let m := mload(0x40)
mstore(m, 0x927da105)
{
let addressMask := shr(96, not(0))
mstore(add(m, 0x20), and(addressMask, owner))
mstore(add(m, 0x40), and(addressMask, token))
mstore(add(m, 0x60), and(addressMask, spender))
mstore(add(m, 0xc0), and(addressMask, spender))
}
let p := mul(PERMIT2, iszero(shr(160, amount)))
if iszero(
and(
gt(returndatasize(), 0x5f),
staticcall(gas(), p, add(m, 0x1c), 0x64, add(m, 0x60), 0x60)
)
) {
mstore(0x00, 0x6b836e6b8757f0fd)
revert(add(0x18, shl(2, iszero(p))), 0x04)
}
mstore(m, 0x2b67b570)
mstore(add(m, 0x60), amount)
mstore(add(m, 0x80), 0xffffffffffff)
mstore(add(m, 0xe0), deadline)
mstore(add(m, 0x100), 0x100)
mstore(add(m, 0x120), 0x41)
mstore(add(m, 0x140), r)
mstore(add(m, 0x160), s)
mstore(add(m, 0x180), shl(248, v))
if iszero(call(gas(), p, 0, add(m, 0x1c), 0x184, codesize(), 0x00)) {
mstore(0x00, 0x6b836e6b)
revert(0x1c, 0x04)
}
}
}
}
{
"compilationTarget": {
"src/IETH.sol": "IETH"
},
"evmVersion": "cancun",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 9999999
},
"remappings": [
":forge-std/=lib/forge-std/src/",
":solady/=lib/solady/src/"
],
"viaIR": true
}
[{"inputs":[],"stateMutability":"payable","type":"constructor"},{"inputs":[],"name":"InsufficientSwap","type":"error"},{"inputs":[],"name":"InvalidCharacter","type":"error"},{"inputs":[],"name":"InvalidSelector","type":"error"},{"inputs":[],"name":"InvalidSwap","type":"error"},{"inputs":[],"name":"InvalidSyntax","type":"error"},{"inputs":[],"name":"Overflow","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"string","name":"name","type":"string"}],"name":"NameSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token0","type":"address"},{"indexed":false,"internalType":"address","name":"token1","type":"address"},{"indexed":false,"internalType":"address","name":"pair","type":"address"}],"name":"PairSet","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[{"internalType":"string","name":"name","type":"string"}],"name":"addresses","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"intent","type":"string"},{"components":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"bytes","name":"initCode","type":"bytes"},{"internalType":"bytes","name":"callData","type":"bytes"},{"internalType":"bytes32","name":"accountGasLimits","type":"bytes32"},{"internalType":"uint256","name":"preVerificationGas","type":"uint256"},{"internalType":"bytes32","name":"gasFees","type":"bytes32"},{"internalType":"bytes","name":"paymasterAndData","type":"bytes"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct IETH.PackedUserOperation","name":"userOp","type":"tuple"}],"name":"checkUserOp","outputs":[{"internalType":"bool","name":"intentMatched","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string[]","name":"intents","type":"string[]"}],"name":"command","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"string","name":"intent","type":"string"}],"name":"command","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"addresses","type":"address"}],"name":"names","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token0","type":"address"},{"internalType":"address","name":"token1","type":"address"}],"name":"pairs","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"intent","type":"string"}],"name":"previewCommand","outputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"minAmountOut","type":"uint256"},{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes","name":"callData","type":"bytes"},{"internalType":"bytes","name":"executeCallData","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"to","type":"string"},{"internalType":"string","name":"amount","type":"string"},{"internalType":"string","name":"token","type":"string"}],"name":"send","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"contract INAMI","name":"NAMI","type":"address"}],"name":"setNAMI","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"string","name":"name","type":"string"}],"name":"setName","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"setName","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"address","name":"pair","type":"address"}],"name":"setPair","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"string","name":"amountIn","type":"string"},{"internalType":"string","name":"amountOutMin","type":"string"},{"internalType":"string","name":"tokenIn","type":"string"},{"internalType":"string","name":"tokenOut","type":"string"},{"internalType":"string","name":"receiver","type":"string"}],"name":"swap","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"callData","type":"bytes"}],"name":"translateCommand","outputs":[{"internalType":"string","name":"intent","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"callData","type":"bytes"}],"name":"translateExecute","outputs":[{"internalType":"string","name":"intent","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"bytes","name":"initCode","type":"bytes"},{"internalType":"bytes","name":"callData","type":"bytes"},{"internalType":"bytes32","name":"accountGasLimits","type":"bytes32"},{"internalType":"uint256","name":"preVerificationGas","type":"uint256"},{"internalType":"bytes32","name":"gasFees","type":"bytes32"},{"internalType":"bytes","name":"paymasterAndData","type":"bytes"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct IETH.PackedUserOperation","name":"userOp","type":"tuple"}],"name":"translateUserOp","outputs":[{"internalType":"string","name":"intent","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"}],"name":"whatIsTheAddressOf","outputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"bytes32","name":"node","type":"bytes32"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]