verified sourcesolidity · v0.8.34+commit.80d5c536
nameRobinHoodBridgeSettleroptimizationenabled (2000 runs)evm versionosakalicensenoneverified at2026-07-21deployer0xe8Cad1…c759creation tx0x35321d9 src/flat/RobinHoodBridgeSettlerFlat.solentry file
// SPDX-License-Identifier: MIT
pragma solidity =0.8.34 >=0.6.2 >=0.8.25 ^0.8.0 ^0.8.25;
// src/vendor/Clz.sol
library Clz {
/// @dev Count leading zeros.
/// Returns the number of zeros preceding the most significant one bit.
/// If `x` is zero, returns 256.
function clz(uint256 x) internal pure returns (uint256 r) {
assembly ("memory-safe") {
r := clz(x)
}
}
function bitLength(uint256 x) internal pure returns (uint256) {
unchecked {
return 256 - clz(x);
}
}
}
// src/Context.sol
abstract contract AbstractContext {
function _msgSender() internal view virtual returns (address);
function _msgData() internal view virtual returns (bytes calldata);
function _isForwarded() internal view virtual returns (bool);
}
abstract contract Context is AbstractContext {
function _msgSender() internal view virtual override returns (address) {
return msg.sender;
}
function _msgData() internal view virtual override returns (bytes calldata) {
return msg.data;
}
function _isForwarded() internal view virtual override returns (bool) {
return false;
}
}
// src/deployer/DeployerAddress.sol
address constant DEPLOYER = 0x00000000000004533Fe15556B1E086BB1A72cEae;
// src/utils/FastLogic.sol
library FastLogic {
function or(bool a, bool b) internal pure returns (bool r) {
assembly ("memory-safe") {
r := or(a, b)
}
}
function and(bool a, bool b) internal pure returns (bool r) {
assembly ("memory-safe") {
r := mul(a, lt(0x00, b))
}
}
function andNot(bool a, bool b) internal pure returns (bool r) {
assembly ("memory-safe") {
r := mul(a, iszero(b))
}
}
function toUint(bool b) internal pure returns (uint256 r) {
assembly ("memory-safe") {
r := lt(0x00, b)
}
}
}
// src/allowanceholder/IAllowanceHolder.sol
IAllowanceHolder constant ALLOWANCE_HOLDER = IAllowanceHolder(0x0000000000001fF3684f28c67538d4D072C22734);
interface IAllowanceHolder {
/// @notice Executes against `target` with the `data` payload. Prior to execution, token permits
/// are temporarily stored for the duration of the transaction. These permits can be
/// consumed by the `operator` during the execution
/// @notice `operator` consumes the funds during its operations by calling back into
/// `AllowanceHolder` with `transferFrom`, consuming a token permit.
/// @dev Neither `exec` nor `transferFrom` check that `token` contains code.
/// @dev msg.sender is forwarded to target appended to the msg data (similar to ERC-2771)
/// @param operator An address which is allowed to consume the token permits
/// @param token The ERC20 token the caller has authorised to be consumed
/// @param amount The quantity of `token` the caller has authorised to be consumed
/// @param target A contract to execute operations with `data`
/// @param data The data to forward to `target`
/// @return result The returndata from calling `target` with `data`
/// @notice If calling `target` with `data` reverts, the revert is propagated
function exec(address operator, address token, uint256 amount, address payable target, bytes calldata data)
external
payable
returns (bytes memory result);
/// @notice The counterpart to `exec` which allows for the consumption of token permits later
/// during execution
/// @dev *DOES NOT* check that `token` contains code. This function vacuously succeeds if
/// `token` is empty.
/// @dev can only be called by the `operator` previously registered in `exec`
/// @param token The ERC20 token to transfer
/// @param owner The owner of tokens to transfer
/// @param recipient The destination/beneficiary of the ERC20 `transferFrom`
/// @param amount The quantity of `token` to transfer`
/// @return true
function transferFrom(address token, address owner, address recipient, uint256 amount) external returns (bool);
}
// lib/permit2/src/interfaces/IEIP712.sol
interface IEIP712 {
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
// lib/forge-std/src/interfaces/IERC165.sol
interface IERC165 {
/// @notice Query if a contract implements an interface
/// @param interfaceID The interface identifier, as specified in ERC-165
/// @dev Interface identification is specified in ERC-165. This function
/// uses less than 30,000 gas.
/// @return `true` if the contract implements `interfaceID` and
/// `interfaceID` is not 0xffffffff, `false` otherwise
function supportsInterface(bytes4 interfaceID) external view returns (bool);
}
// src/interfaces/IERC1967Proxy.sol
interface IERC1967Proxy {
event Upgraded(address indexed implementation);
function implementation() external view returns (address);
function version() external view returns (string memory);
function upgrade(address newImplementation) external payable returns (bool);
function upgradeAndCall(address newImplementation, bytes calldata data) external payable returns (bool);
}
// lib/forge-std/src/interfaces/IERC20.sol
/// @dev Interface of the ERC20 standard as defined in the EIP.
/// @dev This includes the optional name, symbol, and decimals metadata.
interface IERC20 {
/// @dev Emitted when `value` tokens are moved from one account (`from`) to another (`to`).
event Transfer(address indexed from, address indexed to, uint256 value);
/// @dev Emitted when the allowance of a `spender` for an `owner` is set, where `value`
/// is the new allowance.
event Approval(address indexed owner, address indexed spender, uint256 value);
/// @notice Returns the amount of tokens in existence.
function totalSupply() external view returns (uint256);
/// @notice Returns the amount of tokens owned by `account`.
function balanceOf(address account) external view returns (uint256);
/// @notice Moves `amount` tokens from the caller's account to `to`.
function transfer(address to, uint256 amount) external returns (bool);
/// @notice Returns the remaining number of tokens that `spender` is allowed
/// to spend on behalf of `owner`
function allowance(address owner, address spender) external view returns (uint256);
/// @notice Sets `amount` as the allowance of `spender` over the caller's tokens.
/// @dev Be aware of front-running risks: https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
function approve(address spender, uint256 amount) external returns (bool);
/// @notice Moves `amount` tokens from `from` to `to` using the allowance mechanism.
/// `amount` is then deducted from the caller's allowance.
function transferFrom(address from, address to, uint256 amount) external returns (bool);
/// @notice Returns the name of the token.
function name() external view returns (string memory);
/// @notice Returns the symbol of the token.
function symbol() external view returns (string memory);
/// @notice Returns the decimals places of the token.
function decimals() external view returns (uint8);
}
// src/IERC721Owner.sol
interface IERC721Owner {
function ownerOf(uint256) external view returns (address);
}
// src/interfaces/IMultiCall.sol
interface IMultiCall {
function multicall(bytes[] calldata datas) external;
}
// src/deployer/Nonce.sol
/// @dev if you update this, you also have to update the length of the array `NonceList.List.links` in Deployer.sol
type Nonce is uint32;
function incr(Nonce a) pure returns (Nonce) {
return Nonce.wrap(Nonce.unwrap(a) + 1);
}
function Nonce_gt(Nonce a, Nonce b) pure returns (bool) {
return Nonce.unwrap(a) > Nonce.unwrap(b);
}
function Nonce_eq(Nonce a, Nonce b) pure returns (bool) {
return Nonce.unwrap(a) == Nonce.unwrap(b);
}
function isNull_0(Nonce a) pure returns (bool) {
return Nonce.unwrap(a) == 0;
}
using {incr, Nonce_gt as >, Nonce_eq as ==, isNull_0} for Nonce global;
Nonce constant zero = Nonce.wrap(0);
// src/utils/Panic.sol
library Panic {
function panic(uint256 code) internal pure {
assembly ("memory-safe") {
mstore(0x00, 0x4e487b71) // selector for `Panic(uint256)`
mstore(0x20, code)
revert(0x1c, 0x24)
}
}
// https://docs.soliditylang.org/en/latest/control-structures.html#panic-via-assert-and-error-via-require
uint8 internal constant GENERIC = 0x00;
uint8 internal constant ASSERT_FAIL = 0x01;
uint8 internal constant ARITHMETIC_OVERFLOW = 0x11;
uint8 internal constant DIVISION_BY_ZERO = 0x12;
uint8 internal constant ENUM_CAST = 0x21;
uint8 internal constant CORRUPT_STORAGE_ARRAY = 0x22;
uint8 internal constant POP_EMPTY_ARRAY = 0x31;
uint8 internal constant ARRAY_OUT_OF_BOUNDS = 0x32;
uint8 internal constant OUT_OF_MEMORY = 0x41;
uint8 internal constant ZERO_FUNCTION_POINTER = 0x51;
}
// src/utils/Revert.sol
library Revert {
function _revert(bytes memory reason) internal pure {
assembly ("memory-safe") {
revert(add(reason, 0x20), mload(reason))
}
}
function maybeRevert(bool success, bytes memory reason) internal pure {
if (!success) {
_revert(reason);
}
}
}
// src/vendor/Sqrt.sol
// @author Modified from Solady by Vectorized and Akshay Tarpara https://github.com/Vectorized/solady/blob/1198c9f70b30d472a7d0ec021bec080622191b03/src/utils/clz/FixedPointMathLib.sol#L769-L797 under the MIT license.
library Sqrt {
/// @dev Returns the square root of `x`, rounded maybe-up maybe-down. For expert use only.
function _sqrt(uint256 x) private pure returns (uint256 z) {
assembly ("memory-safe") {
// Initial guess z = 2^⌊(n+1)/2⌋ where n = ⌊log₂(x)⌋. This seed gives ε₁ = 0.0607 after
// one Babylonian step for all inputs. With ε_{n+1} ≈ ε²/2, 6 steps yield 2⁻¹⁶⁰ relative
// error (>128 correct bits).
z := shl(shr(1, sub(256, clz(x))), 1)
// 6 Babylonian steps
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
}
}
/// @dev Returns the square root of `x`, rounded down.
function sqrt(uint256 x) internal pure returns (uint256 z) {
z = _sqrt(x);
assembly ("memory-safe") {
// If `x+1` is a perfect square, the Babylonian method oscillates between ⌊√x⌋ and
// ⌈√x⌉. Floor it. See:
// https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division
z := sub(z, lt(div(x, z), z))
}
}
/// @dev Returns the square root of `x`, rounded up.
function sqrtUp(uint256 x) internal pure returns (uint256 z) {
z = _sqrt(x);
assembly ("memory-safe") {
// `mul(z, z)` can overflow when `x == type(uint256).max`. This is because `_sqrt(x)`
// can return ⌈√x⌉ when `x + 1` is square. An overflow in `zz` causes a spurious
// round-up (`z` is already rounded up) and causes the result to be `2**128 + 1`, an
// off-by-one. To compensate, we detect this overflow and avoid rounding.
let zz := mul(z, z)
z := add(gt(lt(zz, x), lt(zz, z)), z)
}
}
}
// src/deployer/Feature.sol
type Feature is uint128;
function Feature_eq(Feature a, Feature b) pure returns (bool) {
return Feature.unwrap(a) == Feature.unwrap(b);
}
function isNull_1(Feature a) pure returns (bool) {
return Feature.unwrap(a) == 0;
}
using {Feature_eq as ==, isNull_1} for Feature global;
function wrap(uint256 x) pure returns (Feature) {
if (x > type(uint128).max) {
Panic.panic(Panic.ARITHMETIC_OVERFLOW);
}
if (x == 0) {
Panic.panic(Panic.ENUM_CAST);
}
return Feature.wrap(uint128(x));
}
// src/interfaces/IOwnable.sol
interface IOwnable is IERC165 {
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
function owner() external view returns (address);
function transferOwnership(address) external returns (bool);
error PermissionDenied();
error ZeroAddress();
}
// src/interfaces/ISettlerBase.sol
interface ISettlerBase {
struct AllowedSlippage {
address payable recipient;
IERC20 buyToken;
uint256 minAmountOut;
}
}
// lib/permit2/src/interfaces/ISignatureTransfer.sol
/// @title SignatureTransfer
/// @notice Handles ERC20 token transfers through signature based actions
/// @dev Requires user's token approval on the Permit2 contract
interface ISignatureTransfer is IEIP712 {
/// @notice Thrown when the requested amount for a transfer is larger than the permissioned amount
/// @param maxAmount The maximum amount a spender can request to transfer
error InvalidAmount(uint256 maxAmount);
/// @notice Thrown when the number of tokens permissioned to a spender does not match the number of tokens being transferred
/// @dev If the spender does not need to transfer the number of tokens permitted, the spender can request amount 0 to be transferred
error LengthMismatch();
/// @notice Emits an event when the owner successfully invalidates an unordered nonce.
event UnorderedNonceInvalidation(address indexed owner, uint256 word, uint256 mask);
/// @notice The token and amount details for a transfer signed in the permit transfer signature
struct TokenPermissions {
// ERC20 token address
address token;
// the maximum amount that can be spent
uint256 amount;
}
/// @notice The signed permit message for a single token transfer
struct PermitTransferFrom {
TokenPermissions permitted;
// a unique value for every token owner's signature to prevent signature replays
uint256 nonce;
// deadline on the permit signature
uint256 deadline;
}
/// @notice Specifies the recipient address and amount for batched transfers.
/// @dev Recipients and amounts correspond to the index of the signed token permissions array.
/// @dev Reverts if the requested amount is greater than the permitted signed amount.
struct SignatureTransferDetails {
// recipient address
address to;
// spender requested amount
uint256 requestedAmount;
}
/// @notice Used to reconstruct the signed permit message for multiple token transfers
/// @dev Do not need to pass in spender address as it is required that it is msg.sender
/// @dev Note that a user still signs over a spender address
struct PermitBatchTransferFrom {
// the tokens and corresponding amounts permitted for a transfer
TokenPermissions[] permitted;
// a unique value for every token owner's signature to prevent signature replays
uint256 nonce;
// deadline on the permit signature
uint256 deadline;
}
/// @notice A map from token owner address and a caller specified word index to a bitmap. Used to set bits in the bitmap to prevent against signature replay protection
/// @dev Uses unordered nonces so that permit messages do not need to be spent in a certain order
/// @dev The mapping is indexed first by the token owner, then by an index specified in the nonce
/// @dev It returns a uint256 bitmap
/// @dev The index, or wordPosition is capped at type(uint248).max
function nonceBitmap(address, uint256) external view returns (uint256);
/// @notice Transfers a token using a signed permit message
/// @dev Reverts if the requested amount is greater than the permitted signed amount
/// @param permit The permit data signed over by the owner
/// @param owner The owner of the tokens to transfer
/// @param transferDetails The spender's requested transfer details for the permitted token
/// @param signature The signature to verify
function permitTransferFrom(
PermitTransferFrom memory permit,
SignatureTransferDetails calldata transferDetails,
address owner,
bytes calldata signature
) external;
/// @notice Transfers a token using a signed permit message
/// @notice Includes extra data provided by the caller to verify signature over
/// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition
/// @dev Reverts if the requested amount is greater than the permitted signed amount
/// @param permit The permit data signed over by the owner
/// @param owner The owner of the tokens to transfer
/// @param transferDetails The spender's requested transfer details for the permitted token
/// @param witness Extra data to include when checking the user signature
/// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash
/// @param signature The signature to verify
function permitWitnessTransferFrom(
PermitTransferFrom memory permit,
SignatureTransferDetails calldata transferDetails,
address owner,
bytes32 witness,
string calldata witnessTypeString,
bytes calldata signature
) external;
/// @notice Transfers multiple tokens using a signed permit message
/// @param permit The permit data signed over by the owner
/// @param owner The owner of the tokens to transfer
/// @param transferDetails Specifies the recipient and requested amount for the token transfer
/// @param signature The signature to verify
function permitTransferFrom(
PermitBatchTransferFrom memory permit,
SignatureTransferDetails[] calldata transferDetails,
address owner,
bytes calldata signature
) external;
/// @notice Transfers multiple tokens using a signed permit message
/// @dev The witness type string must follow EIP712 ordering of nested structs and must include the TokenPermissions type definition
/// @notice Includes extra data provided by the caller to verify signature over
/// @param permit The permit data signed over by the owner
/// @param owner The owner of the tokens to transfer
/// @param transferDetails Specifies the recipient and requested amount for the token transfer
/// @param witness Extra data to include when checking the user signature
/// @param witnessTypeString The EIP-712 type definition for remaining string stub of the typehash
/// @param signature The signature to verify
function permitWitnessTransferFrom(
PermitBatchTransferFrom memory permit,
SignatureTransferDetails[] calldata transferDetails,
address owner,
bytes32 witness,
string calldata witnessTypeString,
bytes calldata signature
) external;
/// @notice Invalidates the bits specified in mask for the bitmap at the word position
/// @dev The wordPos is maxed at type(uint248).max
/// @param wordPos A number to index the nonceBitmap at
/// @param mask A bitmap masked against msg.sender's current bitmap at the word position
function invalidateUnorderedNonces(uint256 wordPos, uint256 mask) external;
}
// src/vendor/SafeTransferLib.sol
/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.
/// @author Modified from Solady (https://github.com/vectorized/solady/blob/main/src/utils/SafeTransferLib.sol)
/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol)
/// @dev Note that none of the functions in this library check that a token has code at all! That responsibility is delegated to the caller.
library SafeTransferLib {
/*//////////////////////////////////////////////////////////////
ETH OPERATIONS
//////////////////////////////////////////////////////////////*/
function safeTransferETH(address payable to, uint256 amount) internal {
assembly ("memory-safe") {
// Transfer the ETH and revert if it fails.
if iszero(call(gas(), to, amount, 0x00, 0x00, 0x00, 0x00)) {
let ptr := mload(0x40)
returndatacopy(ptr, 0x00, returndatasize())
revert(ptr, returndatasize())
}
}
}
/*//////////////////////////////////////////////////////////////
ERC20 OPERATIONS
//////////////////////////////////////////////////////////////*/
function fastBalanceOf(IERC20 token, address acct) internal view returns (uint256 r) {
assembly ("memory-safe") {
mstore(0x14, acct) // Store the `acct` argument.
mstore(0x00, 0x70a08231000000000000000000000000) // Selector for `balanceOf(address)`, with `acct`'s padding.
// Call and check for revert. Storing the selector with padding in
// memory at 0 results in a start of calldata at offset 16. Calldata
// is 36 bytes long (4 bytes selector, 32 bytes argument)
if iszero(staticcall(gas(), token, 0x10, 0x24, 0x00, 0x20)) {
let ptr := mload(0x40)
returndatacopy(ptr, 0x00, returndatasize())
revert(ptr, returndatasize())
}
// Check for short returndata and missing code
if iszero(lt(0x1f, returndatasize())) { revert(0x00, 0x00) }
r := mload(0x00)
}
}
function safeTransferFrom(IERC20 token, address from, address to, uint256 amount) internal {
assembly ("memory-safe") {
let ptr := mload(0x40) // Cache the free memory pointer.
mstore(0x60, amount) // Store the `amount` argument.
mstore(0x40, to) // Store the `to` argument.
mstore(0x2c, shl(0x60, from)) // Store the `from` argument. (Clears `to`'s padding.)
mstore(0x0c, 0x23b872dd000000000000000000000000) // Selector for `transferFrom(address,address,uint256)`, with `from`'s padding.
// Calldata starts at offset 28 and is 100 bytes long (3 * 32 + 4).
// If there is returndata (optional) we copy the first 32 bytes into the first slot of memory.
if iszero(call(gas(), token, 0x00, 0x1c, 0x64, 0x00, 0x20)) {
returndatacopy(ptr, 0x00, returndatasize())
revert(ptr, returndatasize())
}
// We check that the call either returned exactly 1 [true] (can't just be non-zero
// data), or had no return data.
if iszero(or(and(eq(mload(0x00), 0x01), lt(0x1f, returndatasize())), iszero(returndatasize()))) {
mstore(0x00, 0x7939f424) // Selector for `TransferFromFailed()`
revert(0x1c, 0x04)
}
mstore(0x60, 0x00) // Restore the zero slot to zero.
mstore(0x40, ptr) // Restore the free memory pointer.
}
}
function safeTransfer(IERC20 token, address to, uint256 amount) internal {
assembly ("memory-safe") {
mstore(0x14, to) // Store the `to` argument.
mstore(0x34, amount) // Store the `amount` argument.
// Storing `amount` clobbers the upper bits of the free memory pointer, but those bits
// can never be set without running into an OOG, so it's safe. We'll restore them to
// zero at the end.
mstore(0x00, 0xa9059cbb000000000000000000000000) // Selector for `transfer(address,uint256)`, with `to`'s padding.
// Calldata starts at offset 16 and is 68 bytes long (2 * 32 + 4).
// If there is returndata (optional) we copy the first 32 bytes into the first slot of memory.
if iszero(call(gas(), token, 0x00, 0x10, 0x44, 0x00, 0x20)) {
let ptr := and(0xffffff, mload(0x40))
returndatacopy(ptr, 0x00, returndatasize())
revert(ptr, returndatasize())
}
// We check that the call either returned exactly 1 [true] (can't just be non-zero
// data), or had no return data.
if iszero(or(and(eq(mload(0x00), 0x01), lt(0x1f, returndatasize())), iszero(returndatasize()))) {
mstore(0x00, 0x90b8ec18) // Selector for `TransferFailed()`
revert(0x1c, 0x04)
}
mstore(0x34, 0x00) // Restore the part of the free memory pointer that was overwritten.
}
}
function safeApprove(IERC20 token, address to, uint256 amount) internal {
assembly ("memory-safe") {
mstore(0x14, to) // Store the `to` argument.
mstore(0x34, amount) // Store the `amount` argument.
// Storing `amount` clobbers the upper bits of the free memory pointer, but those bits
// can never be set without running into an OOG, so it's safe. We'll restore them to
// zero at the end.
mstore(0x00, 0x095ea7b3000000000000000000000000) // Selector for `approve(address,uint256)`, with `to`'s padding.
// Calldata starts at offset 16 and is 68 bytes long (2 * 32 + 4).
// If there is returndata (optional) we copy the first 32 bytes into the first slot of memory.
if iszero(call(gas(), token, 0x00, 0x10, 0x44, 0x00, 0x20)) {
let ptr := and(0xffffff, mload(0x40))
returndatacopy(ptr, 0x00, returndatasize())
revert(ptr, returndatasize())
}
// We check that the call either returned exactly 1 [true] (can't just be non-zero
// data), or had no return data.
if iszero(or(and(eq(mload(0x00), 0x01), lt(0x1f, returndatasize())), iszero(returndatasize()))) {
mstore(0x00, 0x3e3f8f73) // Selector for `ApproveFailed()`
revert(0x1c, 0x04)
}
mstore(0x34, 0x00) // Restore the part of the free memory pointer that was overwritten.
}
}
function safeApproveIfBelow(IERC20 token, address spender, uint256 amount) internal {
uint256 allowance;
assembly ("memory-safe") {
// Save the free memory pointer for restoration after we clobber it
let ptr := mload(0x40)
mstore(0x40, spender)
mstore(0x2c, shl(0x60, address())) // Also clears `spender`'s padding
mstore(0x0c, 0xdd62ed3e000000000000000000000000) // Selector for `allowance(address,address)` with `address()`'s padding
// Calldata starts at offset 28 and is 68 bytes long
if iszero(staticcall(gas(), token, 0x1c, 0x44, 0x00, 0x20)) {
returndatacopy(ptr, 0x00, returndatasize())
revert(ptr, returndatasize())
}
// Revert on short returndata
if gt(0x20, returndatasize()) {
revert(0x00, 0x00)
}
allowance := mload(0x00)
// Restore the free memory pointer
mstore(0x40, ptr)
}
if (allowance < amount) {
if (allowance != 0) {
safeApprove(token, spender, 0);
}
safeApprove(token, spender, type(uint256).max);
}
}
}
// src/core/SettlerErrors.sol
/// @notice Thrown when an offset is not the expected value
error InvalidOffset();
/// @notice Thrown when a validating a target contract to avoid certain types of targets
error ConfusedDeputy();
function revertConfusedDeputy() pure {
assembly ("memory-safe") {
mstore(0x00, 0xe758b8d5) // selector for `ConfusedDeputy()`
revert(0x1c, 0x04)
}
}
/// @notice Thrown when a target contract is invalid given the context
error InvalidTarget();
/// @notice Thrown when validating the caller against the expected caller
error InvalidSender();
/// @notice Thrown in cases when using a Trusted Forwarder / AllowanceHolder is not allowed
error ForwarderNotAllowed();
/// @notice Thrown when a signature length is not the expected length
error InvalidSignatureLen();
/// @notice Thrown when a slippage limit is exceeded
error TooMuchSlippage(IERC20 token, uint256 expected, uint256 actual);
function revertTooMuchSlippage(IERC20 buyToken, uint256 expectedBuyAmount, uint256 actualBuyAmount) pure {
assembly ("memory-safe") {
mstore(0x54, actualBuyAmount)
mstore(0x34, expectedBuyAmount)
mstore(0x14, buyToken)
mstore(0x00, 0x97a6f3b9000000000000000000000000) // selector for `TooMuchSlippage(address,uint256,uint256)` with `buyToken`'s padding
revert(0x10, 0x64)
}
}
/// @notice Thrown when a byte array that is supposed to encode a function from ISettlerActions is
/// not recognized in context.
error ActionInvalid(uint256 i, bytes4 action, bytes data);
function revertActionInvalid(uint256 i, uint256 action, bytes calldata data) pure {
assembly ("memory-safe") {
let ptr := mload(0x40)
mstore(ptr, 0x3c74eed6) // selector for `ActionInvalid(uint256,bytes4,bytes)`
mstore(add(0x20, ptr), i)
mstore(add(0x40, ptr), shl(0xe0, action)) // align as `bytes4`
mstore(add(0x60, ptr), 0x60) // offset to the length slot of the dynamic value `data`
mstore(add(0x80, ptr), data.length)
calldatacopy(add(0xa0, ptr), data.offset, data.length)
revert(add(0x1c, ptr), add(0x84, data.length))
}
}
/// @notice Thrown when the encoded fork ID as part of UniswapV3 fork path is not on the list of
/// recognized forks for this chain.
error UnknownForkId(uint8 forkId);
function revertUnknownForkId(uint8 forkId) pure {
assembly ("memory-safe") {
mstore(0x00, 0xd3b1276d) // selector for `UnknownForkId(uint8)`
mstore(0x20, and(0xff, forkId))
revert(0x1c, 0x24)
}
}
/// @notice Thrown when an AllowanceHolder transfer's permit is past its deadline
error SignatureExpired(uint256 deadline);
/// @notice Thrown when selling the native asset, but `msg.value` exceeds the value from the generated quote
error MsgValueMismatch(uint256 expected, uint256 actual);
/// @notice An internal error that should never be thrown. Thrown when a callback reenters the
/// entrypoint and attempts to clobber the existing callback.
error ReentrantCallback(uint256 callbackInt);
/// @notice An internal error that should never be thrown. This error can only be thrown by
/// non-metatx-supporting Settler instances. Thrown when a callback-requiring liquidity
/// source is called, but Settler never receives the callback.
error CallbackNotSpent(uint256 callbackInt);
/// @notice Thrown when a metatransaction has reentrancy.
error ReentrantMetatransaction(bytes32 oldWitness);
/// @notice Thrown when any transaction has reentrancy, not just taker-submitted or metatransaction.
error ReentrantPayer(address oldPayer);
/// @notice An internal error that should never be thrown. Thrown when a metatransaction fails to
/// spend a coupon.
error WitnessNotSpent(bytes32 oldWitness);
/// @notice An internal error that should never be thrown. Thrown when the payer is unset
/// unexpectedly.
error PayerSpent();
error DeltaNotPositive(IERC20 token);
error DeltaNotNegative(IERC20 token);
error ZeroSellAmount(IERC20 token);
error ZeroBuyAmount(IERC20 buyToken);
error BoughtSellToken(IERC20 sellToken);
error TokenHashCollision(IERC20 token0, IERC20 token1);
error ZeroToken();
/// @notice Thrown for liquidities that require a Newton-Raphson approximation to solve their
/// constant function when Newton-Raphson fails to converge on the solution in a
/// "reasonable" number of iterations.
error NotConverged();
/// @notice Thrown when the encoded pool manager ID as part of PancakeSwap Infinity fill is not on
/// the list of recognized pool managers.
error UnknownPoolManagerId(uint8 poolManagerId);
/// @notice Thrown when the `msg.value` is less than the minimum expected value.
error Underpayment(uint256 msgValueMin, uint256 msgValueActual);
/// @notice Thrown when a permit call fails.
error PermitFailed();
/// @notice Thrown when a permit signature is incorrect
error InvalidSignature();
/// @notice Thrown when a permit signature is expired
error PermitExpired();
/// @notice Thrown when a permit type is unsupported
error UnsupportedPermitType();
/// @notice Thrown when a CCIP message specifies a non-zero feeToken (only native fees are supported)
error InvalidFeeToken();
/// @notice Thrown when a CCIP message does not have exactly 1 tokenAmounts element
error InvalidTokenAmountsLength();
// src/utils/Ternary.sol
library Ternary {
//// All the code duplication in this file is because solc isn't smart enough to figure out that
//// it doesn't need to do a ton of masking when types are cast to each other without
//// modification.
function ternary(bool c, uint256 x, uint256 y) internal pure returns (uint256 r) {
assembly ("memory-safe") {
r := xor(x, mul(xor(x, y), iszero(c)))
}
}
function ternary(bool c, int256 x, int256 y) internal pure returns (int256 r) {
assembly ("memory-safe") {
r := xor(x, mul(xor(x, y), iszero(c)))
}
}
function ternary(bool c, bytes4 x, bytes4 y) internal pure returns (bytes4 r) {
assembly ("memory-safe") {
r := xor(x, mul(xor(x, y), iszero(c)))
}
}
function ternary(bool c, address x, address y) internal pure returns (address r) {
assembly ("memory-safe") {
r := xor(x, mul(xor(x, y), iszero(c)))
}
}
function orZero(bool c, uint256 x) internal pure returns (uint256 r) {
assembly ("memory-safe") {
r := mul(lt(0x00, c), x)
}
}
function maybeSwap(bool c, uint256 x, uint256 y) internal pure returns (uint256 a, uint256 b) {
assembly ("memory-safe") {
let t := mul(iszero(c), xor(y, x))
a := xor(y, t)
b := xor(x, t)
}
}
function maybeSwap(bool c, int256 x, int256 y) internal pure returns (int256 a, int256 b) {
assembly ("memory-safe") {
let t := mul(iszero(c), xor(y, x))
a := xor(y, t)
b := xor(x, t)
}
}
function maybeSwap(bool c, IERC20 x, IERC20 y) internal pure returns (IERC20 a, IERC20 b) {
assembly ("memory-safe") {
let t := mul(iszero(c), xor(y, x))
a := xor(y, t)
b := xor(x, t)
}
}
function maybeSwap(bool c, address x, address y) internal pure returns (address a, address b) {
assembly ("memory-safe") {
let t := mul(iszero(c), xor(y, x))
a := xor(y, t)
b := xor(x, t)
}
}
}
// src/utils/UnsafeMath.sol
library UnsafeMath {
function unsafeInc(uint256 x) internal pure returns (uint256) {
unchecked {
return x + 1;
}
}
function unsafeInc(uint256 x, bool b) internal pure returns (uint256 r) {
assembly ("memory-safe") {
r := add(x, lt(0x00, b))
}
}
function unsafeInc(int256 x) internal pure returns (int256) {
unchecked {
return x + 1;
}
}
function unsafeDec(uint256 x) internal pure returns (uint256) {
unchecked {
return x - 1;
}
}
function unsafeDec(uint256 x, bool b) internal pure returns (uint256 r) {
assembly ("memory-safe") {
r := sub(x, lt(0x00, b))
}
}
function unsafeDec(int256 x) internal pure returns (int256) {
unchecked {
return x - 1;
}
}
function unsafeNeg(int256 x) internal pure returns (int256) {
unchecked {
return -x;
}
}
function unsafeAbs(int256 x) internal pure returns (uint256 r) {
assembly ("memory-safe") {
r := mul(or(0x01, sar(0xff, x)), x)
}
}
function unsafeDiv(uint256 numerator, uint256 denominator) internal pure returns (uint256 quotient) {
assembly ("memory-safe") {
quotient := div(numerator, denominator)
}
}
function unsafeDiv(int256 numerator, int256 denominator) internal pure returns (int256 quotient) {
assembly ("memory-safe") {
quotient := sdiv(numerator, denominator)
}
}
function unsafeMod(uint256 numerator, uint256 denominator) internal pure returns (uint256 remainder) {
assembly ("memory-safe") {
remainder := mod(numerator, denominator)
}
}
function unsafeMod(int256 numerator, int256 denominator) internal pure returns (int256 remainder) {
assembly ("memory-safe") {
remainder := smod(numerator, denominator)
}
}
function unsafeMulMod(uint256 a, uint256 b, uint256 m) internal pure returns (uint256 r) {
assembly ("memory-safe") {
r := mulmod(a, b, m)
}
}
function unsafeAddMod(uint256 a, uint256 b, uint256 m) internal pure returns (uint256 r) {
assembly ("memory-safe") {
r := addmod(a, b, m)
}
}
function unsafeDivUp(uint256 n, uint256 d) internal pure returns (uint256 r) {
assembly ("memory-safe") {
r := add(gt(mod(n, d), 0x00), div(n, d))
}
}
/// rounds away from zero
function unsafeDivOut(int256 n, int256 d) internal pure returns (int256 r) {
assembly ("memory-safe") {
let s := sar(0xff, xor(n, d))
let c := lt(0x00, smod(n, d))
r := add(sdiv(n, d), sub(xor(s, c), s))
}
}
function unsafeAdd(uint256 a, uint256 b) internal pure returns (uint256 r) {
assembly ("memory-safe") {
r := add(a, b)
}
}
}
library Math {
function inc(uint256 x, bool c) internal pure returns (uint256 r) {
assembly ("memory-safe") {
r := add(x, lt(0x00, c))
}
if (r < x) {
Panic.panic(Panic.ARITHMETIC_OVERFLOW);
}
}
function dec(uint256 x, bool c) internal pure returns (uint256 r) {
assembly ("memory-safe") {
r := sub(x, lt(0x00, c))
}
if (r > x) {
Panic.panic(Panic.ARITHMETIC_OVERFLOW);
}
}
function toInt(bool c) internal pure returns (uint256 r) {
assembly ("memory-safe") {
r := lt(0x00, c)
}
}
function saturatingAdd(uint256 x, uint256 y) internal pure returns (uint256 r) {
assembly ("memory-safe") {
r := add(x, y)
r := or(r, sub(0x00, lt(r, y)))
}
}
function saturatingSub(uint256 x, uint256 y) internal pure returns (uint256 r) {
assembly ("memory-safe") {
r := mul(gt(x, y), sub(x, y))
}
}
function absDiff(uint256 x, uint256 y) internal pure returns (uint256 r, bool sign) {
assembly ("memory-safe") {
sign := lt(x, y)
let m := sub(0x00, sign)
r := sub(xor(sub(x, y), m), m)
}
}
}
// src/allowanceholder/AllowanceHolderContext.sol
abstract contract AllowanceHolderContext is Context {
function _isForwarded() internal view virtual override returns (bool) {
return super._isForwarded() || super._msgSender() == address(ALLOWANCE_HOLDER);
}
function _msgData() internal view virtual override returns (bytes calldata) {
if (super._msgSender() == address(ALLOWANCE_HOLDER)) {
return msg.data[:msg.data.length - 20];
} else {
return msg.data;
}
}
function _msgSender() internal view virtual override returns (address sender) {
sender = super._msgSender();
if (sender == address(ALLOWANCE_HOLDER)) {
// ERC-2771 like usage where the _trusted_ `AllowanceHolder` has appended the appropriate
// msg.sender to the msg data
bytes calldata data = super._msgData();
assembly ("memory-safe") {
sender := shr(0x60, calldataload(add(data.offset, sub(data.length, 0x14))))
}
}
}
// this is here to avoid foot-guns and make it very explicit that we intend
// to pass the confused deputy check in AllowanceHolder
function balanceOf(address) external pure {
assembly ("memory-safe") {
mstore8(0x00, 0x00)
return(0x00, 0x01)
}
}
}
// src/core/CCIP.sol
/// @dev Interface for CCIP Router
interface IRouterClient {
struct EVMTokenAmount {
address token;
uint256 amount;
}
struct EVM2AnyMessage {
bytes receiver;
bytes data;
EVMTokenAmount[] tokenAmounts;
address feeToken;
bytes extraArgs;
}
function ccipSend(uint64 destinationChainSelector, EVM2AnyMessage calldata message)
external
payable
returns (bytes32);
function getFee(uint64 destinationChainSelector, EVM2AnyMessage calldata message) external view returns (uint256);
function isChainSupported(uint64 chainSelector) external view returns (bool);
}
interface IOnRamp {
/// @dev Matches Internal.EVM2EVMMessage from the CCIP onRamp for event decoding
struct EVM2EVMMessage {
uint64 sourceChainSelector;
address sender;
address receiver;
uint64 sequenceNumber;
uint256 gasLimit;
bool strict;
uint64 nonce;
address feeToken;
uint256 feeTokenAmount;
bytes data;
IRouterClient.EVMTokenAmount[] tokenAmounts;
bytes[] sourceTokenData;
bytes32 messageId;
}
}
/// @title CCIP
/// @notice Chainlink CCIP bridge integration for BridgeSettler
/// @dev Handles ERC20 token bridging via CCIP with native token fee payment
contract CCIP {
using SafeTransferLib for IERC20;
/// @notice Bridge ERC20 tokens via CCIP, paying fees in native token
/// @param router The CCIP router address
/// @param ccipSendData Encoded call to `IRouterClient.ccipSend` without selector
function bridgeToCCIP(address router, bytes memory ccipSendData) internal {
IERC20 token;
uint256 tokenAmountsPtr;
// Check ccipSendData and get the bridged token
assembly ("memory-safe") {
// ccipSendData layout:
// +0x00: ccipSendData length
// +0x20: destinationChainSelector
// +0x40: offset to IRouterClient.EVM2AnyMessage
let dataStart := add(0x20, ccipSendData) // skip bytes length
// Malformed offsets are treated as GIGO errors. If they don't result in an OOG/OOM
// error, they might affect token detection and amount override, which will result in
// a malformed call to CCIP and most likely a revert.
let msgOffset := mload(add(0x20, dataStart)) // offset to EVM2AnyMessage
let msgPtr := add(dataStart, msgOffset) // pointer to message struct
// IRouterClient.EVM2AnyMessage layout (at msgPtr):
// +0x00: offset to receiver
// +0x20: offset to data
// +0x40: offset to tokenAmounts
// +0x60: feeToken
// +0x80: offset to extraArgs
//
// Verify feeToken is address(0) - only native token fees are supported
if mload(add(0x60, msgPtr)) {
mstore(0x00, 0x6cb99623) // selector for `InvalidFeeToken()`
revert(0x1c, 0x04)
}
// See above comment about malformed offsets.
let tokensOffset := mload(add(0x40, msgPtr)) // offset to tokenAmounts array
tokenAmountsPtr := add(msgPtr, tokensOffset) // pointer to tokenAmounts array
// IRouterClient.EVMTokenAmount[] tokenAmounts array (at tokensPtr, assuming 1 element):
// +0x00: array length (should be 1)
// +0x20: tokenAmounts[0].token
// +0x40: tokenAmounts[0].amount
//
// Verify tokenAmounts array has exactly 1 element
if xor(0x01, mload(tokenAmountsPtr)) {
mstore(0x00, 0x2c419a85) // selector for `InvalidTokenAmountsLength()`
revert(0x1c, 0x04)
}
// read token from tokenAmounts[0]
token := mload(add(0x20, tokenAmountsPtr))
}
uint256 amount = token.fastBalanceOf(address(this));
token.safeApproveIfBelow(router, amount);
assembly ("memory-safe") {
// Update the amount
mstore(add(0x40, tokenAmountsPtr), amount)
// Temporarily clobber the bytes length slot with the function selector
let len := mload(ccipSendData)
mstore(ccipSendData, 0x96f4e9f9) // selector for `IRouterClient.ccipSend`
// Call the `router` with the full balance for fee, any excess is donated to CCIP.
// `router` is user-provided but we're calling a specific function `IRouterClient.ccipSend`
// which doesn't clash with restricted targets (AllowanceHolder & Permit2)
if iszero(call(gas(), router, selfbalance(), add(0x1c, ccipSendData), add(0x04, len), 0x00, 0x00)) {
let ptr := mload(0x40)
returndatacopy(ptr, 0x00, returndatasize())
revert(ptr, returndatasize())
}
// Restore clobbered memory
mstore(ccipSendData, len)
}
}
}
// src/bridge/IBridgeSettlerActions.sol
interface IBridgeSettlerActions {
/// @dev Transfer funds from msg.sender Permit2.
function TRANSFER_FROM(address recipient, ISignatureTransfer.PermitTransferFrom memory permit, bytes memory sig)
external;
/// @dev Execute swaps in Settler
function SETTLER_SWAP(address token, uint256 amount, address settler, bytes calldata settlerData) external;
/// @dev msgValueMin is interpreted as an lower bound on the expected msg.value, not as an exact specification
function UNDERPAYMENT_CHECK(uint256 msgValueMin) external;
/// @dev Bridge through a Bridge that follows the approval, transferFrom(msg.sender) interaction
/// Pre-req: Funded
function BASIC(address bridgeToken, uint256 bps, address pool, uint256 offset, bytes calldata data) external;
/// @dev Bridge ERC20 tokens through Relay
function BRIDGE_ERC20_TO_RELAY(address token, address to, bytes32 requestId) external;
/// @dev Bridge native tokens through Relay
function BRIDGE_NATIVE_TO_RELAY(address to, bytes32 requestId) external;
/// @dev Bridge ERC20 through Mayan
function BRIDGE_ERC20_TO_MAYAN(bytes calldata protocolAndData) external;
/// @dev Bridge native through Mayan
function BRIDGE_NATIVE_TO_MAYAN(bytes calldata protocolAndData) external;
/// @dev Bridge ERC20 through Across
function BRIDGE_ERC20_TO_ACROSS(address spoke, bytes calldata depositData) external;
/// @dev Bridge native through Across
function BRIDGE_NATIVE_TO_ACROSS(address spoke, bytes calldata depositData) external;
/// @dev Bridge through StargateV2
function BRIDGE_TO_STARGATE_V2(address token, address pool, bytes calldata sendData) external;
/// @dev Bridge ERC20 through LayerZeroOFT
function BRIDGE_TO_LAYER_ZERO_OFT(address token, address oft, bytes calldata sendData) external;
/// @dev Bridge ERC20 through DeBridge
function BRIDGE_TO_DEBRIDGE(uint256 globalFee, bytes calldata createOrderData) external;
/// @dev Bridge ERC20 through Chainlink CCIP, paying fees in native token
function BRIDGE_TO_CCIP(address router, bytes calldata ccipSendData) external;
/// @dev Bridge WPAXG through Nucleus Teller, paying fees in native token.
function BRIDGE_TO_NUCLEUS_TELLER(bytes calldata bridgeCallData) external;
/// @dev Wraps PAXG into WPAXG and bridges the resulting shares through Nucleus Teller,
/// paying fees in native token.
function DEPOSIT_AND_BRIDGE_TO_NUCLEUS_TELLER(bytes calldata depositAndBridgeCallData) external;
}
// src/ISettlerActions.sol
interface ISettlerActions {
/// VIP actions should always start with `recipient` address and the `permit` from the taker
/// followed by all the other parameters to ensure compatibility with `executeWithPermit` entrypoint.
/// `minBuyAmount`/`amountOutMin` should always be the last parameter.
/// @dev Transfer funds from msg.sender Permit2.
function TRANSFER_FROM(address recipient, ISignatureTransfer.PermitTransferFrom memory permit, bytes memory sig)
external;
// @dev msgValue is interpreted as an upper bound on the expected msg.value, not as an exact specification
function NATIVE_CHECK(uint256 deadline, uint256 msgValue) external;
/// @dev Transfer funds from metatransaction requestor into the Settler contract using Permit2. Only for use in `Settler.executeMetaTxn` where the signature is provided as calldata
function METATXN_TRANSFER_FROM(address recipient, ISignatureTransfer.PermitTransferFrom memory permit) external;
/// @dev Settle an RfqOrder between maker and taker transfering funds directly between the parties
// Post-req: Payout if recipient != taker
function RFQ_VIP(
address recipient,
ISignatureTransfer.PermitTransferFrom memory takerPermit,
ISignatureTransfer.PermitTransferFrom memory makerPermit,
address maker,
bytes memory makerSig,
bytes memory takerSig
) external;
/// @dev Settle an RfqOrder between maker and taker transfering funds directly between the parties for the entire amount
function METATXN_RFQ_VIP(
address recipient,
ISignatureTransfer.PermitTransferFrom memory takerPermit,
ISignatureTransfer.PermitTransferFrom memory makerPermit,
address maker,
bytes memory makerSig
) external;
/// @dev Settle an RfqOrder between Maker and Settler. Transfering funds from the Settler contract to maker.
/// Retaining funds in the settler contract.
// Pre-req: Funded
// Post-req: Payout
function RFQ(
address recipient,
ISignatureTransfer.PermitTransferFrom memory permit,
address maker,
bytes memory makerSig,
address takerToken,
uint256 maxTakerAmount
) external;
function UNISWAPV4(
address recipient,
address sellToken,
uint256 bps,
bool feeOnTransfer,
uint256 hashMul,
uint256 hashMod,
bytes memory fills,
uint256 amountOutMin
) external;
function UNISWAPV4_VIP(
address recipient,
ISignatureTransfer.PermitTransferFrom memory permit,
bool feeOnTransfer,
uint256 hashMul,
uint256 hashMod,
bytes memory fills,
bytes memory sig,
uint256 amountOutMin
) external;
function METATXN_UNISWAPV4_VIP(
address recipient,
ISignatureTransfer.PermitTransferFrom memory permit,
bool feeOnTransfer,
uint256 hashMul,
uint256 hashMod,
bytes memory fills,
uint256 amountOutMin
) external;
function BALANCERV3(
address recipient,
address sellToken,
uint256 bps,
bool feeOnTransfer,
uint256 hashMul,
uint256 hashMod,
bytes memory fills,
uint256 amountOutMin
) external;
function BALANCERV3_VIP(
address recipient,
ISignatureTransfer.PermitTransferFrom memory permit,
bool feeOnTransfer,
uint256 hashMul,
uint256 hashMod,
bytes memory fills,
bytes memory sig,
uint256 amountOutMin
) external;
function METATXN_BALANCERV3_VIP(
address recipient,
ISignatureTransfer.PermitTransferFrom memory permit,
bool feeOnTransfer,
uint256 hashMul,
uint256 hashMod,
bytes memory fills,
uint256 amountOutMin
) external;
function PANCAKE_INFINITY(
address recipient,
address sellToken,
uint256 bps,
bool feeOnTransfer,
uint256 hashMul,
uint256 hashMod,
bytes memory fills,
uint256 amountOutMin
) external;
function PANCAKE_INFINITY_VIP(
address recipient,
ISignatureTransfer.PermitTransferFrom memory permit,
bool feeOnTransfer,
uint256 hashMul,
uint256 hashMod,
bytes memory fills,
bytes memory sig,
uint256 amountOutMin
) external;
function METATXN_PANCAKE_INFINITY_VIP(
address recipient,
ISignatureTransfer.PermitTransferFrom memory permit,
bool feeOnTransfer,
uint256 hashMul,
uint256 hashMod,
bytes memory fills,
uint256 amountOutMin
) external;
/// @dev Trades against UniswapV3 using the contracts balance for funding
// Pre-req: Funded
// Post-req: Payout
function UNISWAPV3(address recipient, uint256 bps, bytes memory path, uint256 amountOutMin) external;
/// @dev Trades against UniswapV3 using user funds via Permit2 for funding
function UNISWAPV3_VIP(
address recipient,
ISignatureTransfer.PermitTransferFrom memory permit,
bytes memory path,
bytes memory sig,
uint256 amountOutMin
) external;
/// @dev Trades against UniswapV3 using user funds via Permit2 for funding. Metatransaction variant. Signature is over all actions.
function METATXN_UNISWAPV3_VIP(
address recipient,
ISignatureTransfer.PermitTransferFrom memory permit,
bytes memory path,
uint256 amountOutMin
) external;
function MAKERPSM(address recipient, uint256 bps, bool buyGem, uint256 amountOutMin, address psm, address dai)
external;
function CURVE_TRICRYPTO_VIP(
address recipient,
ISignatureTransfer.PermitTransferFrom memory permit,
uint80 poolInfo,
bytes memory sig,
uint256 minBuyAmount
) external;
function METATXN_CURVE_TRICRYPTO_VIP(
address recipient,
ISignatureTransfer.PermitTransferFrom memory permit,
uint80 poolInfo,
uint256 minBuyAmount
) external;
function DODOV1(address sellToken, uint256 bps, address pool, bool quoteForBase, uint256 minBuyAmount) external;
function DODOV2(
address recipient,
address sellToken,
uint256 bps,
address pool,
bool quoteForBase,
uint256 minBuyAmount
) external;
function VELODROME(address recipient, uint256 bps, address pool, uint24 swapInfo, uint256 minBuyAmount) external;
/// @dev Trades against MaverickV2 using the contracts balance for funding
/// This action does not use the MaverickV2 callback, so it takes an arbitrary pool address to make calls against.
/// Passing `tokenAIn` as a parameter actually saves gas relative to introspecting the pool's `tokenA()` accessor.
function MAVERICKV2(
address recipient,
address sellToken,
uint256 bps,
address pool,
bool tokenAIn,
int32 tickLimit,
uint256 minBuyAmount
) external;
/// @dev Trades against UniswapV2 using the contracts balance for funding
/// @param swapInfo is encoded as the upper 16 bits as the fee of the pool in bps, the second
/// lowest bit as "sell token has transfer fee", and the lowest bit as the
/// "token0 for token1" flag.
function UNISWAPV2(
address recipient,
address sellToken,
uint256 bps,
address pool,
uint24 swapInfo,
uint256 amountOutMin
) external;
function POSITIVE_SLIPPAGE(address payable recipient, address token, uint256 expectedAmount, uint256 maxBps)
external;
/// @dev Trades against a basic AMM which follows the approval, transferFrom(msg.sender) interaction
// Pre-req: Funded
// Post-req: Payout
function BASIC(address sellToken, uint256 bps, address pool, uint256 offset, bytes calldata data) external;
function EKUBO(
address recipient,
address sellToken,
uint256 bps,
bool feeOnTransfer,
uint256 hashMul,
uint256 hashMod,
bytes memory fills,
uint256 amountOutMin
) external;
function EKUBOV3(
address recipient,
address sellToken,
uint256 bps,
bool feeOnTransfer,
uint256 hashMul,
uint256 hashMod,
bytes memory fills,
uint256 amountOutMin
) external;
function EKUBOV3_VIP(
address recipient,
ISignatureTransfer.PermitTransferFrom memory permit,
bool feeOnTransfer,
uint256 hashMul,
uint256 hashMod,
bytes memory fills,
bytes memory sig,
uint256 amountOutMin
) external;
function METATXN_EKUBOV3_VIP(
address recipient,
ISignatureTransfer.PermitTransferFrom memory permit,
bool feeOnTransfer,
uint256 hashMul,
uint256 hashMod,
bytes memory fills,
uint256 amountOutMin
) external;
function EULERSWAP(
address recipient,
address sellToken,
uint256 bps,
address pool,
bool zeroForOne,
uint256 amountOutMin
) external;
function RENEGADE(address target, address sellToken, bool baseForQuote, bytes memory data, uint256 minBuyAmount)
external;
struct BebopMakerSignature {
bytes signatureBytes;
uint256 flags;
}
struct BebopOrder {
uint256 expiry;
address maker_address;
uint256 maker_nonce;
address maker_token;
uint256 taker_amount;
uint256 maker_amount;
// the high 5 bits are unused
// the next 3 bits are the `takerHasNative`, `makerHasNative`, and
// `takerUsingPermit2` flags (in that order from high to low) from the
// original `packed_commands` field
// the next 120 bits are unused
// the low 128 bits are the `event_id` from the original `flags` field
uint256 event_id_and_flags;
}
function BEBOP(
address recipient,
address sellToken,
BebopOrder memory order,
BebopMakerSignature memory makerSignature,
uint256 amountOutMin
) external;
function HANJI(
address sellToken,
uint256 bps,
address pool,
uint256 sellScalingFactor,
uint256 buyScalingFactor,
bool isAsk,
uint256 priceLimit,
uint256 minBuyAmount
) external;
function CHECK_SLIPPAGE(bool transferExactLimit) external;
}
// src/core/LayerZeroOFT.sol
interface IOFT {
event OFTSent(
bytes32 indexed guid, uint32 dstEid, address indexed fromAddress, uint256 amountSentLD, uint256 amountReceivedLD
);
struct SendParam {
uint32 dstEid;
bytes32 to;
uint256 amountLD;
uint256 minAmountLD;
bytes extraOptions;
bytes composeMsg;
bytes oftCmd;
}
struct MessagingFee {
uint256 nativeFee;
uint256 lzTokenFee;
}
struct OFTLimit {
uint256 minAmountLD;
uint256 maxAmountLD;
}
struct OFTReceipt {
uint256 amountSentLD;
uint256 amountReceivedLD;
}
struct OFTFeeDetail {
int256 feeAmountLD;
string description;
}
function send(SendParam memory sendParam, MessagingFee memory messagingFee, address refundAddress) external;
function quoteOFT(SendParam ca