Source Code
Overview
ETH Balance
0 ETH
ETH Value
$0.00Multichain Info
N/A
| Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
Advanced mode: Intended for advanced users or developers and will display all Internal Transactions including zero value transfers.
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Block | From | To | ||||
|---|---|---|---|---|---|---|---|
| 15813583 | 2 days ago | 0 ETH | |||||
| 15813583 | 2 days ago | 0 ETH | |||||
| 15813486 | 2 days ago | 0 ETH | |||||
| 15813486 | 2 days ago | 0 ETH | |||||
| 15813486 | 2 days ago | 0 ETH | |||||
| 15556097 | 4 days ago | 0 ETH | |||||
| 15556097 | 4 days ago | 0 ETH | |||||
| 15556072 | 4 days ago | 0 ETH | |||||
| 15556072 | 4 days ago | 0 ETH | |||||
| 15541746 | 5 days ago | 0 ETH | |||||
| 15541746 | 5 days ago | 0 ETH | |||||
| 15541746 | 5 days ago | 0 ETH | |||||
| 15541717 | 5 days ago | 0 ETH | |||||
| 15541717 | 5 days ago | 0 ETH | |||||
| 15541717 | 5 days ago | 0 ETH | |||||
| 15245530 | 8 days ago | 0 ETH | |||||
| 15245530 | 8 days ago | 0 ETH | |||||
| 15245510 | 8 days ago | 0 ETH | |||||
| 15245510 | 8 days ago | 0 ETH | |||||
| 15114823 | 10 days ago | 0 ETH | |||||
| 15114823 | 10 days ago | 0 ETH | |||||
| 14959324 | 11 days ago | 0 ETH | |||||
| 14959324 | 11 days ago | 0 ETH | |||||
| 14959324 | 11 days ago | 0 ETH | |||||
| 14917994 | 12 days ago | 0 ETH |
Cross-Chain Transactions
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
CallForwarder
Compiler Version
v0.8.28+commit.7893614a
Optimization Enabled:
Yes with 1000000 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.28;
import {ComposerCommands} from "../enums/DeltaEnums.sol";
import {Transfers} from "../transfers/Transfers.sol";
import {ExternalCallsGeneric} from "../generic/ExternalCallsGeneric.sol";
import {BridgeForwarder} from "./bridges/BridgeForwarder.sol";
/**
* @notice An arbitrary call contract to forward generic calls
* Does pull funds if desired
* One transfers funds to this contract and operates with them, ideally pre-funded
* All composer transfer options are available (approve,transferFrom,transfer,native transfers)
* Can generically call any target and checks if the selector for these calls is not `transferFrom`
* We assume that this contract is never an approve target!
*/
contract CallForwarder is Transfers, ExternalCallsGeneric, BridgeForwarder {
// base receive function
receive() external payable {}
/**
* A selector different to the classic Composer
* Should be called by a more universal composer
* that cannot call arbitrary selectors.
*/
function deltaForwardCompose(bytes calldata) external payable {
uint256 currentOffset;
uint256 endOffset;
address callerAddress;
assembly {
let calldataLength := calldataload(0x24)
currentOffset := 0x44
endOffset := add(currentOffset, calldataLength)
callerAddress := caller()
}
_deltaComposeInternal(callerAddress, currentOffset, endOffset);
}
function _deltaComposeInternal(address callerAddress, uint256 currentOffset, uint256 endOffset) internal virtual override(ExternalCallsGeneric) {
while (true) {
uint256 operation;
assembly {
operation := shr(248, calldataload(currentOffset))
currentOffset := add(1, currentOffset)
}
if (operation == ComposerCommands.EXT_CALL) {
currentOffset = _callExternal(currentOffset);
} else if (operation == ComposerCommands.EXT_TRY_CALL) {
currentOffset = _tryCallExternal(currentOffset, callerAddress);
} else if (operation == ComposerCommands.TRANSFERS) {
currentOffset = _transfers(currentOffset, callerAddress);
} else if (operation == ComposerCommands.BRIDGING) {
currentOffset = _bridge(currentOffset);
} else {
_invalidOperation();
}
// break criteria - we reached the end of the calldata exactly
if (currentOffset >= endOffset) break;
}
// revert if we went past the end
if (currentOffset > endOffset) revert InvalidCalldata();
}
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.28;
/**
* Permit classifier enums
*/
library TransferIds {
uint256 internal constant TRANSFER_FROM = 0;
uint256 internal constant SWEEP = 1;
uint256 internal constant WRAP_NATIVE = 2;
uint256 internal constant UNWRAP_WNATIVE = 3;
uint256 internal constant PERMIT2_TRANSFER_FROM = 4;
uint256 internal constant APPROVE = 5;
}
/**
* Permit classifier enums
*/
library PermitIds {
uint256 internal constant TOKEN_PERMIT = 0;
uint256 internal constant AAVE_V3_CREDIT_PERMIT = 1;
uint256 internal constant ALLOW_CREDIT_PERMIT = 2;
}
/**
* Lender classifier enums, expected to be encoded as uint16
*/
library LenderIds {
uint256 internal constant UP_TO_AAVE_V3 = 1000;
uint256 internal constant UP_TO_AAVE_V2 = 2000;
uint256 internal constant UP_TO_COMPOUND_V3 = 3000;
uint256 internal constant UP_TO_COMPOUND_V2 = 4000;
uint256 internal constant UP_TO_MORPHO = 5000;
}
/**
* Operations enums, encoded as uint8
*/
library LenderOps {
uint256 internal constant DEPOSIT = 0;
uint256 internal constant BORROW = 1;
uint256 internal constant REPAY = 2;
uint256 internal constant WITHDRAW = 3;
uint256 internal constant DEPOSIT_LENDING_TOKEN = 4;
uint256 internal constant WITHDRAW_LENDING_TOKEN = 5;
}
/**
* Lender classifier enums, expected to be encoded as uint16
*/
library FlashLoanIds {
uint256 internal constant MORPHO = 0;
uint256 internal constant BALANCER_V2 = 1;
uint256 internal constant AAVE_V3 = 2;
uint256 internal constant AAVE_V2 = 3;
}
/**
* ERC4626 classifier enums
*/
library ERC4626Ids {
uint256 internal constant DEPOSIT = 0;
uint256 internal constant WITHDRAW = 1;
}
/**
* Uniswp V4 operations outside of swaps
*/
library Gen2025ActionIds {
uint256 internal constant UNLOCK = 0;
uint256 internal constant UNI_V4_TAKE = 1;
uint256 internal constant UNI_V4_SETTLE = 2;
uint256 internal constant UNI_V4_SYNC = 3;
uint256 internal constant BAL_V3_TAKE = 4;
uint256 internal constant BAL_V3_SETTLE = 5;
}
/// @title Commands for OneDeltaComposer
library ComposerCommands {
uint256 internal constant SWAPS = 0x10;
uint256 internal constant EXT_CALL = 0x20;
uint256 internal constant EXT_TRY_CALL = 0x21;
uint256 internal constant LENDING = 0x30;
uint256 internal constant TRANSFERS = 0x40;
uint256 internal constant PERMIT = 0x50;
uint256 internal constant FLASH_LOAN = 0x60;
uint256 internal constant ERC4626 = 0x70;
uint256 internal constant GEN_2025_SINGELTONS = 0x80;
uint256 internal constant BRIDGING = 0x90;
}
/// @title Commands for Bridge
library BridgeIds {
uint256 internal constant STARGATE_V2 = 0x00;
uint256 internal constant ACROSS = 0x0A;
uint256 internal constant SQUID_ROUTER = 0x14;
uint256 internal constant GASZIP = 0x1E;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;
import {ERC20Selectors} from "contracts/1delta/shared/selectors/ERC20Selectors.sol";
import {Masks} from "contracts/1delta/shared/masks/Masks.sol";
import {DeltaErrors} from "contracts/1delta/shared/errors/Errors.sol";
contract BaseUtils is ERC20Selectors, Masks, DeltaErrors {
error InvalidAssetId(uint16 assetId);
error InsufficientValue();
error InsufficientAmount();
error SlippageTooHigh(uint256 expected, uint256 actual);
error ZeroBalance();
error BridgeFailed();
error InvalidDestination();
error InvalidReceiver();
uint256 internal constant FEE_DENOMINATOR = 1e9;
uint256 internal constant INSUFFICIENT_VALUE = 0x1101129400000000000000000000000000000000000000000000000000000000;
uint256 internal constant INSUFFICIENT_AMOUNT = 0x5945ea5600000000000000000000000000000000000000000000000000000000;
uint256 internal constant ZERO_BALANCE = 0x669567ea00000000000000000000000000000000000000000000000000000000;
uint256 internal constant BRIDGE_FAILED = 0xc3b9eede00000000000000000000000000000000000000000000000000000000;
uint256 internal constant INVALID_DESTINATION = 0xac6b05f500000000000000000000000000000000000000000000000000000000;
uint256 internal constant INVALID_RECEIVER = 0x1e4ec46b00000000000000000000000000000000000000000000000000000000;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;
import {BaseUtils} from "contracts/1delta/composer/generic/BaseUtils.sol";
contract Across is BaseUtils {
/**
* @notice Handles Across bridging operations
* @dev Decodes calldata and directly executes the bridge operation using assembly
* @param currentOffset Current position in the calldata
* @return Updated calldata offset after processing
*
* | Offset | Length (bytes) | Description |
* |--------|----------------|------------------------------|
* | 0 | 20 | spokePool |
* | 20 | 20 | depositor |
* | 40 | 20 | inputTokenAddress |
* | 60 | 32 | receivingAssetId |
* | 92 | 16 | amount |
* | 108 | 16 | FixedFee (in input decimals) |
* | 124 | 4 | FeePercentage |
* | 128 | 4 | destinationChainId |
* | 132 | 1 | fromTokenDecimals |
* | 133 | 1 | toTokenDecimals |
* | 134 | 32 | receiver |
* | 166 | 4 | deadline |
* | 170 | 2 | message.length: msgLen |
* | 172 | msgLen | message |
*/
function _bridgeAcross(uint256 currentOffset) internal returns (uint256) {
assembly {
let inputTokenAddress := shr(96, calldataload(add(currentOffset, 40)))
let amount := shr(128, calldataload(add(currentOffset, 92)))
// whether to use native is indicated by the flag
let isNative := and(NATIVE_FLAG, amount)
// clear the native flag
amount := and(amount, not(NATIVE_FLAG))
// get the length as uint16
let messageLength := shr(240, calldataload(add(currentOffset, 170)))
let requiredNativeValue := 0
// Check if amount is zero and handle accordingly
// zero means self balance
switch iszero(amount)
case 1 {
switch isNative
case 0 {
mstore(0, ERC20_BALANCE_OF)
mstore(0x04, address())
pop(staticcall(gas(), inputTokenAddress, 0x0, 0x24, 0x0, 0x20))
amount := mload(0x0)
}
default {
// get native balance
amount := selfbalance()
requiredNativeValue := amount
}
}
// non zero amount
default {
if isNative {
// For native assets, check that hte contract holds enough
if gt(amount, selfbalance()) {
mstore(0, INSUFFICIENT_VALUE)
revert(0, 4)
}
requiredNativeValue := amount
}
}
// ff is the fixed fee here, then it becomes the amount with fixed fee realized
let ff := shr(128, calldataload(add(currentOffset, 108)))
switch gt(amount, ff)
case 1 { ff := sub(amount, ff) }
default {
mstore(0, INSUFFICIENT_AMOUNT)
revert(0, 4)
}
let fromTokenDecimals := calldataload(add(currentOffset, 132))
let toTokenDecimals := and(shr(240, fromTokenDecimals), UINT8_MASK)
fromTokenDecimals := shr(248, fromTokenDecimals)
let decimalDiff := sub(toTokenDecimals, fromTokenDecimals)
let outputAmount := 0
let decimalAdjustment := 1
if xor(fromTokenDecimals, toTokenDecimals) {
// abs(decimalDiff)
let mask := sar(255, decimalDiff)
let absDiff := sub(xor(decimalDiff, mask), mask)
switch absDiff
// shorthands
case 12 { decimalAdjustment := 1000000000000 }
case 11 { decimalAdjustment := 100000000000 }
case 10 { decimalAdjustment := 10000000000 }
case 9 { decimalAdjustment := 1000000000 }
case 8 { decimalAdjustment := 100000000 }
case 7 { decimalAdjustment := 10000000 }
case 6 { decimalAdjustment := 1000000 }
// arbitrary loop
default { for { let i := 0 } lt(i, absDiff) { i := add(i, 1) } { decimalAdjustment := mul(decimalAdjustment, 10) } }
}
// calculate percentage fee with decimal adjustment
switch lt(toTokenDecimals, fromTokenDecimals)
case 1 {
outputAmount := div(mul(amount, shr(224, calldataload(add(currentOffset, 124)))), mul(FEE_DENOMINATOR, decimalAdjustment))
ff := div(ff, decimalAdjustment) // apply decimal adjustment on amount with fixed fee
}
// none or output has more decimals
default {
outputAmount := div(mul(decimalAdjustment, mul(amount, shr(224, calldataload(add(currentOffset, 124))))), FEE_DENOMINATOR)
ff := mul(ff, decimalAdjustment) // apply decimal adjustment on amount with fixed fee
} // also handles the case where decimals are the same
switch gt(ff, outputAmount)
case 1 { outputAmount := sub(ff, outputAmount) }
default {
mstore(0, INSUFFICIENT_AMOUNT)
revert(0, 4)
}
let ptr := mload(0x40)
// deposit function selector
mstore(ptr, 0xad5425c600000000000000000000000000000000000000000000000000000000)
mstore(add(ptr, 0x04), shr(96, calldataload(add(currentOffset, 20)))) // depositor
mstore(add(ptr, 0x24), calldataload(add(currentOffset, 134))) // recipient (32 bytes)
mstore(add(ptr, 0x44), inputTokenAddress) // inputToken
mstore(add(ptr, 0x64), calldataload(add(currentOffset, 60))) // outputToken (32 bytes)
mstore(add(ptr, 0x84), amount) // amount
mstore(add(ptr, 0xa4), outputAmount) // outputAmount
mstore(add(ptr, 0xc4), shr(224, calldataload(add(currentOffset, 128)))) // destinationChainId
mstore(add(ptr, 0xe4), 0) // exclusiveRelayer (zero address)
mstore(add(ptr, 0x104), timestamp()) // quoteTimestamp (block timestamp)
// fillDeadline (exact deadline)
mstore(add(ptr, 0x124), shr(224, calldataload(add(currentOffset, 166))))
mstore(add(ptr, 0x144), 0) // exclusivityDeadline (zero)
mstore(add(ptr, 0x164), 0x180) // message offset
mstore(add(ptr, 0x184), messageLength) // message length
// Handle message
switch gt(messageLength, 0)
case 1 {
// add the message from the calldata
calldatacopy(add(ptr, 0x1a4), add(currentOffset, 172), messageLength)
// call and forward error
if iszero(
call(
gas(),
shr(96, calldataload(currentOffset)), // spoke pool address
requiredNativeValue,
ptr,
add(0x1a4, messageLength), // add length of variable data
0x00,
0x00
)
) {
returndatacopy(0, 0, returndatasize())
revert(0, returndatasize())
}
mstore(0x40, add(ptr, add(0x1c4, messageLength))) // one word after the message
}
default {
// call and forward error
if iszero(
call(
gas(),
shr(96, calldataload(currentOffset)), // spoke pool address
requiredNativeValue,
ptr,
0x1a4,
0x00,
0x00
)
) {
returndatacopy(0, 0, returndatasize())
revert(0, returndatasize())
}
mstore(0x40, add(ptr, 0x1a4)) // one word after the message
}
currentOffset := add(currentOffset, add(172, messageLength))
}
return currentOffset;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;
import {StargateV2} from "./StargateV2/StargateV2.sol";
import {Across} from "./Across/Across.sol";
import {SquidRouter} from "./Squid_Router/SquidRouter.sol";
import {GasZip} from "./GasZip/GasZip.sol";
import {BridgeIds} from "contracts/1delta/composer/enums/DeltaEnums.sol";
/**
* Aggregates multiple bridge calls
*/
contract BridgeForwarder is StargateV2, Across, SquidRouter, GasZip {
function _bridge(uint256 currentOffset) internal returns (uint256) {
uint256 bridgeOperation;
assembly {
let firstSlice := calldataload(currentOffset)
bridgeOperation := shr(248, firstSlice)
currentOffset := add(currentOffset, 1)
}
if (bridgeOperation == BridgeIds.STARGATE_V2) {
return _bridgeStargateV2(currentOffset);
} else if (bridgeOperation == BridgeIds.ACROSS) {
return _bridgeAcross(currentOffset);
} else if (bridgeOperation == BridgeIds.SQUID_ROUTER) {
return _bridgeSquidRouter(currentOffset);
} else if (bridgeOperation == BridgeIds.GASZIP) {
return _bridgeGasZip(currentOffset);
} else {
_invalidOperation();
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;
import {BaseUtils} from "contracts/1delta/composer/generic/BaseUtils.sol";
contract GasZip is BaseUtils {
/**
* @notice Handles GasZip bridging (GasZip v1)
* https://dev.gas.zip/gas/code-examples/evm-deposit/contract-forwarder
*
* | Offset | Length (bytes) | Description |
* |--------|----------------|------------------------------|
* | 0 | 20 | gasZipRouter |
* | 20 | 32 | receiver |
* | 52 | 16 | amount |
* | 68 | 32 | destinatinChainId |
*/
function _bridgeGasZip(uint256 currentOffset) internal returns (uint256) {
assembly {
function revertWith(code) {
mstore(0, code)
revert(0, 0x4)
}
let gasZipRouter := shr(96, calldataload(currentOffset))
let receiver := calldataload(add(currentOffset, 20))
let amount := shr(128, calldataload(add(currentOffset, 52)))
let destinatinChainId := calldataload(add(currentOffset, 68))
currentOffset := add(currentOffset, 100)
// amount zero means sefbalance
switch iszero(amount)
case 1 {
amount := selfbalance()
// revert if no balance to send
if iszero(amount) { revertWith(ZERO_BALANCE) }
}
// prevent same-chain
if eq(destinatinChainId, chainid()) { revertWith(INVALID_DESTINATION) }
// check that receiver is nonzero
if iszero(receiver) { revertWith(INVALID_RECEIVER) }
let ptr := mload(0x40)
// deposit(uint256 destinationChains, bytes32 to)
mstore(ptr, 0xc9630cb000000000000000000000000000000000000000000000000000000000)
mstore(add(ptr, 0x04), destinatinChainId)
mstore(add(ptr, 0x24), receiver)
if iszero(call(gas(), gasZipRouter, amount, ptr, 0x44, 0, 0)) {
returndatacopy(0, 0, returndatasize())
revert(0, returndatasize())
}
}
return currentOffset;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;
import {BaseUtils} from "contracts/1delta/composer/generic/BaseUtils.sol";
contract SquidRouter is BaseUtils {
/**
* @notice Handles SquidRouter bridging operations
* @param currentOffset Current position in the calldata
* @return Updated calldata offset after processing
*
* Generic layout:
* | Offset | Length (bytes) | Description |
* |--------|----------------|--------------------------------------------|
* | 0 | 20 | gateway |
* | 20 | 20 | token to be bridged |
*/
function _bridgeSquidRouter(uint256 currentOffset) internal returns (uint256) {
address gateway;
address asset;
assembly {
gateway := shr(96, calldataload(currentOffset))
currentOffset := add(currentOffset, 20)
asset := shr(96, calldataload(currentOffset))
currentOffset := add(currentOffset, 20)
}
return _squidRouterBridgeCall(gateway, asset, currentOffset);
}
/*
*
* | Offset | Length (bytes) | Description |
* |--------------|----------------|--------------------------------------------|
* | 0 | 2 | bridgedTokenSymbol.length: sl |
* | 2 | 2 | destinationChain.length: dl |
* | 4 | 2 | destinationAddress.length: al |
* | 6 | 2 | payload.length: pl |
* | 8 | 16 | amount |
* | 24 | 16 | nativeAmount |
* | 40 | 20 | gasRefundRecipient |
* | 60 | 1 | enableExpress |
* | 61 | s1 | bridgedTokenSymbol |
* | 61+s1 | dl | destinationChain |
* | 61+s1+dl | al | destinationAddress |
* | 61+s1+dl+al | pl | payload |
*/
function _squidRouterBridgeCall(address gateway, address asset, uint256 currentOffset) private returns (uint256 ptr) {
assembly {
ptr := mload(0x40)
{
let firstThenAmount := calldataload(currentOffset)
let symbolLen := shr(240, firstThenAmount)
let destLen := shr(240, shl(16, firstThenAmount))
let contractAddrLen := shr(240, shl(32, firstThenAmount))
let payloadLen := shr(240, shl(48, firstThenAmount))
firstThenAmount := shr(128, shl(64, firstThenAmount))
let nativeAmount := shr(128, calldataload(add(currentOffset, 24)))
if gt(nativeAmount, selfbalance()) {
mstore(0x00, INSUFFICIENT_VALUE)
revert(0x00, 0x04)
}
let gasRefundRecipient := calldataload(add(currentOffset, 40))
let enableExpress := and(UINT8_MASK, shr(88, gasRefundRecipient))
gasRefundRecipient := shr(96, gasRefundRecipient)
// set and store amount
switch firstThenAmount
// zero-> selfbalance
case 0 {
mstore(0x00, ERC20_BALANCE_OF)
mstore(0x04, address())
pop(staticcall(gas(), asset, 0x00, 0x24, 0x00, 0x20))
mstore(add(ptr, 128), mload(0x00))
}
// provided amount
default { mstore(add(ptr, 128), firstThenAmount) }
mstore(ptr, symbolLen)
mstore(add(ptr, 32), destLen)
mstore(add(ptr, 64), contractAddrLen)
mstore(add(ptr, 96), payloadLen)
// mstore(add(ptr, 128), amount)
mstore(add(ptr, 160), nativeAmount)
mstore(add(ptr, 192), gasRefundRecipient)
mstore(add(ptr, 224), enableExpress)
currentOffset := add(currentOffset, 61)
}
// offsets (for strings and bytes)
let off1
let off2
let off3
let off4
let total
{
// zero padding length
let padLen1 := and(add(mload(ptr), 31), not(31))
let padLen2 := and(add(mload(add(ptr, 32)), 31), not(31))
let padLen3 := and(add(mload(add(ptr, 64)), 31), not(31))
let padLen4 := and(add(mload(add(ptr, 96)), 31), not(31))
// offsets (for strings and bytes)
off1 := 224 // 7 args, 7 * 32 = 224
off2 := add(off1, add(32, padLen1))
off3 := add(off2, add(32, padLen2))
off4 := add(off3, add(32, padLen3))
// 4 (selector) + 224 head + dynamic sections (padded lengths + 128)
total := add(356, add(add(padLen1, padLen2), add(padLen3, padLen4)))
}
mstore(add(ptr, 256), 0x2147796000000000000000000000000000000000000000000000000000000000)
let head := add(ptr, 260)
// head (7 args)
mstore(head, off1)
mstore(add(head, 32), mload(add(ptr, 128))) // amount
mstore(add(head, 64), off2)
mstore(add(head, 96), off3)
mstore(add(head, 128), off4)
mstore(add(head, 160), mload(add(ptr, 192))) // gasRefundRecipient
mstore(add(head, 192), mload(add(ptr, 224))) // enableExpress
function copyTo(_head, _at, offs, currOffs) -> newOffs {
let p := add(_head, offs)
let l := mload(_at)
mstore(p, l)
calldatacopy(add(p, 32), currOffs, l)
newOffs := add(currOffs, l)
}
// bridgedTokenSymbol
currentOffset := copyTo(head, ptr, off1, currentOffset)
// destinationChain
currentOffset := copyTo(head, add(ptr, 32), off2, currentOffset)
// destinationAddress
currentOffset := copyTo(head, add(ptr, 64), off3, currentOffset)
// payload
currentOffset := copyTo(head, add(ptr, 96), off4, currentOffset)
mstore(0x40, add(add(ptr, 256), total))
if iszero(call(gas(), gateway, mload(add(ptr, 160)), add(ptr, 256), total, 0, 0)) {
returndatacopy(0, 0, returndatasize())
revert(0, returndatasize())
}
// set ptr to offset as return value
ptr := currentOffset
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;
import {BaseUtils} from "contracts/1delta/composer/generic/BaseUtils.sol";
contract StargateV2 is BaseUtils {
/**
* @notice Handles Stargate V2 bridging operations
* @dev Decodes calldata and forwards the call to the appropriate Stargate adapter function
* @param currentOffset Current position in the calldata
* @return Updated calldata offset after processing
*
* | Offset | Length (bytes) | Description |
* |--------------|----------------|------------------------------|
* | 0 | 20 | tokenAddress |
* | 20 | 20 | stargate pool |
* | 40 | 4 | dstEid |
* | 44 | 32 | receiver |
* | 76 | 20 | refundReceiver |
* | 96 | 16 | amount |
* | 112 | 4 | slippage |
* | 116 | 16 | fee |
* | 132 | 1 | isBusMode |
* | 133 | 2 | composeMsg.length: cl |
* | 135 | 2 | extraOptions.length: el |
* | 137 | cl | composeMsg |
* | 137+cl | el | extraOptions |
*/
function _bridgeStargateV2(uint256 currentOffset) internal returns (uint256) {
assembly {
function revertWith(code) {
mstore(0, code)
revert(0, 4)
}
function getBalance(token) -> b {
mstore(0, ERC20_BALANCE_OF)
mstore(0x04, address())
pop(staticcall(gas(), token, 0x0, 0x24, 0x0, 0x20))
b := mload(0x0)
}
let asset
let composeMsgLength
let extraOptionsLength
let amount
let requiredValue
let fee
let minAmountLD
// underlying (=0 means native)
asset := shr(96, calldataload(currentOffset))
// native fee
fee := shr(128, calldataload(add(currentOffset, 116)))
// get bytes lenght
composeMsgLength := shr(240, calldataload(add(currentOffset, 133)))
extraOptionsLength := shr(240, calldataload(add(currentOffset, 135)))
amount := shr(128, calldataload(add(currentOffset, 96)))
// native flag is high bit
let isNative := and(NATIVE_FLAG, amount)
// clear the native flag
amount := and(amount, not(NATIVE_FLAG))
let slfBal := selfbalance()
// check if amount is 0
switch iszero(amount)
case 1 {
// native is asset = 0
switch isNative
case 0 {
// use token balance
amount := getBalance(asset)
// value to send is just the fee
requiredValue := fee
// check if fee is enough
if gt(requiredValue, slfBal) { revertWith(INSUFFICIENT_VALUE) }
}
default {
// amount is the balance minus the fee
amount := sub(slfBal, fee)
// and value to send is everything
requiredValue := slfBal
}
}
default {
// native is asset = 0
switch isNative
case 0 {
// erc20 case: value is just the fee
requiredValue := fee
}
default {
// value to send is amount desired plus fee
requiredValue := add(amount, fee)
}
// check if we have enough to pay the fee
if gt(requiredValue, slfBal) { revertWith(INSUFFICIENT_VALUE) }
}
// amount adjusted for slippage
minAmountLD :=
div(
mul(
amount,
sub(
FEE_DENOMINATOR,
shr(224, calldataload(add(currentOffset, 112))) // slippage (assured to not overflow)
)
),
FEE_DENOMINATOR
)
// Set up function call memory
let ptr := mload(0x40)
// sendToken selector: 0xcbef2aa9
mstore(ptr, 0xcbef2aa900000000000000000000000000000000000000000000000000000000)
// sendParam struct
mstore(add(ptr, 0x04), 128)
// nativeFee
mstore(add(ptr, 0x24), fee)
// lzTokenFee
mstore(add(ptr, 0x44), 0)
// refund address
mstore(add(ptr, 0x64), shr(96, calldataload(add(currentOffset, 76))))
// sendParam struct
mstore(add(ptr, 0x84), shr(224, calldataload(add(currentOffset, 40))))
mstore(add(ptr, 0xa4), calldataload(add(currentOffset, 44)))
mstore(add(ptr, 0xc4), amount)
mstore(add(ptr, 0xe4), minAmountLD)
// byte offsets
// extraOptions offset
mstore(add(ptr, 0x104), 0xe0) // this one is fixed
// composeMsg offset
let composeMsgOffset
switch iszero(extraOptionsLength)
case 1 { composeMsgOffset := 0x120 }
case 0 {
let divResult := div(extraOptionsLength, 32)
let modResult := mod(extraOptionsLength, 32)
let numWords
switch gt(modResult, 0)
case 1 { numWords := add(divResult, 1) }
default { numWords := divResult }
composeMsgOffset := add(0xe0, mul(0x20, add(numWords, 1))) // +1 for the extraOptions's length
}
mstore(add(ptr, 0x124), composeMsgOffset)
// oftCmd offset
let oftCmdOffset
switch iszero(composeMsgLength)
case 1 { oftCmdOffset := add(composeMsgOffset, 0x20) }
default {
let divResult := div(composeMsgLength, 32)
let modResult := mod(composeMsgLength, 32)
let numWords
switch gt(modResult, 0)
case 1 { numWords := add(divResult, 1) }
default { numWords := divResult }
oftCmdOffset := add(composeMsgOffset, mul(0x20, add(numWords, 1))) // +1 for the composeMsg's length
}
mstore(add(ptr, 0x144), oftCmdOffset)
// extraOptions
let extraOptionsPtr := add(ptr, 0x164) // fixed one, relative to ptr
mstore(extraOptionsPtr, extraOptionsLength)
if gt(extraOptionsLength, 0) {
calldatacopy(add(extraOptionsPtr, 0x20), add(add(currentOffset, 137), composeMsgLength), extraOptionsLength)
}
// composeMsg
let composeMsgPtr := add(composeMsgOffset, add(ptr, 0x84))
mstore(composeMsgPtr, composeMsgLength)
if gt(composeMsgLength, 0) { calldatacopy(add(composeMsgPtr, 0x20), add(currentOffset, 137), composeMsgLength) }
let callSize // callsize for calling stargate
// oftCmd
let oftCmdPtr := add(oftCmdOffset, add(ptr, 0x84))
switch iszero(
shr(248, calldataload(add(currentOffset, 132))) // isTaxiMode flag (already masked)
)
case 1 {
mstore(oftCmdPtr, 0x0)
callSize := sub(add(oftCmdPtr, 0x20), ptr) // add only length word
}
default {
mstore(oftCmdPtr, 0x20)
mstore(add(oftCmdPtr, 0x20), 0)
callSize := sub(add(oftCmdPtr, 0x40), ptr) // add length and busMode flag
}
// Update free memory pointer
mstore(0x40, add(ptr, callSize))
if iszero(call(gas(), shr(96, calldataload(add(currentOffset, 20))), requiredValue, ptr, callSize, 0, 0)) {
returndatacopy(0, 0, returndatasize())
revert(0, returndatasize())
}
currentOffset := add(add(add(currentOffset, 137), composeMsgLength), extraOptionsLength)
}
return currentOffset;
}
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.28;
import {BaseUtils} from "contracts/1delta/composer/generic/BaseUtils.sol";
// solhint-disable max-line-length
/**
* @notice External call on any target - prevents `transferFrom` selector & call on Permit2
*/
abstract contract ExternalCallsGeneric is BaseUtils {
/// @dev mask for selector in calldata
bytes32 private constant SELECTOR_MASK = 0xffffffff00000000000000000000000000000000000000000000000000000000;
// Forbidden()
bytes4 private constant FORBIDDEN = 0xee90c468;
function _callExternal(uint256 currentOffset) internal returns (uint256) {
/*
* | Offset | Length (bytes) | Description |
* |--------|----------------|----------------------|
* | 0 | 20 | target |
* | 20 | 16 | nativeValue |
* | 36 | 2 | calldataLength: cl |
* | 38 | cl | calldata |
*/
assembly {
// get first three addresses
let target := shr(96, calldataload(currentOffset))
// prevent calls to permit2
if eq(target, 0x000000000022D473030F116dDEE9F6B43aC78BA3) {
mstore(0x0, FORBIDDEN)
revert(0x0, 0x4)
}
currentOffset := add(20, currentOffset)
let callValue := shr(128, calldataload(currentOffset))
currentOffset := add(16, currentOffset)
let dataLength := shr(240, calldataload(currentOffset))
currentOffset := add(2, currentOffset)
switch and(NATIVE_FLAG, callValue)
case 0 { callValue := and(callValue, UINT120_MASK) }
default { callValue := selfbalance() }
// free memo ptr for populating the tx
let ptr := mload(0x40)
// extract the selector from the calldata
// and check if it is `transferFrom`
if eq(and(SELECTOR_MASK, calldataload(currentOffset)), ERC20_TRANSFER_FROM) {
mstore(0x0, FORBIDDEN)
revert(0x0, 0x4)
}
// copy calldata
calldatacopy(ptr, currentOffset, dataLength)
if iszero(
call(
gas(),
target,
callValue,
ptr, //
dataLength,
// the length must be correct or the call will fail
0x0, // output = empty
0x0 // output size = zero
)
) {
returndatacopy(0, 0, returndatasize())
revert(0, returndatasize())
}
// increment offset by data length
currentOffset := add(currentOffset, dataLength)
}
return currentOffset;
}
function _tryCallExternal(uint256 currentOffset, address callerAddress) internal returns (uint256) {
/*
* | Offset | Length (bytes) | Description |
* |--------|----------------|----------------------|
* | 0 | 20 | target |
* | 20 | 16 | nativeValue |
* | 36 | 2 | calldataLength: cl |
* | 38 | cl | calldata |
* | 38+cl | 1 | catchHandling | <- 0: revert; 1: exit in catch if revert; else continue after catch
* | 39+cl | 2 | catchDataLength: dl |
* | 41+cl | dl | catchData |
*/
bool success;
uint256 catchHandling;
uint256 catchCalldataLength;
assembly {
let target := shr(96, calldataload(currentOffset))
// prevent calls to permit2
if eq(target, 0x000000000022D473030F116dDEE9F6B43aC78BA3) {
mstore(0x0, FORBIDDEN)
revert(0x0, 0x4)
}
currentOffset := add(20, currentOffset)
let callValue := shr(128, calldataload(currentOffset))
currentOffset := add(16, currentOffset)
let dataLength := shr(240, calldataload(currentOffset))
currentOffset := add(2, currentOffset)
switch and(NATIVE_FLAG, callValue)
case 0 { callValue := and(callValue, UINT120_MASK) }
default { callValue := selfbalance() }
// free memo ptr for populating the tx
let ptr := mload(0x40)
// extract the selector from the calldata
// and check if it is `transferFrom`
if eq(and(SELECTOR_MASK, calldataload(currentOffset)), ERC20_TRANSFER_FROM) {
mstore(0x0, FORBIDDEN)
revert(0x0, 0x4)
}
// copy calldata
calldatacopy(ptr, currentOffset, dataLength)
success :=
call(
gas(),
target,
callValue,
ptr, //
dataLength,
// the length must be correct or the call will fail
0x0, // output = empty
0x0 // output size = zero
)
// increment offset by data length
currentOffset := add(currentOffset, dataLength)
let nexstSlice := calldataload(currentOffset)
// top byte of next slice
catchHandling := shr(248, nexstSlice)
// case: 0 revert if not successful
if and(iszero(catchHandling), iszero(success)) {
returndatacopy(0, 0, returndatasize())
revert(0, returndatasize())
}
catchCalldataLength := and(UINT16_MASK, shr(232, nexstSlice))
currentOffset := add(currentOffset, 3)
}
// execution logic on failute
if (!success) {
// Catch and run fallback
// execute further calldata if provided
if (catchCalldataLength > 0) {
// Calculate the absolute end position for the catch data (last param of the _deltaComposeInternal)
uint256 catchMaxIndex = currentOffset + catchCalldataLength;
_deltaComposeInternal(callerAddress, currentOffset, catchMaxIndex);
// Update currentOffset to the end of catch data
currentOffset = catchMaxIndex;
}
// case 1 - exit function execution here
if (catchHandling == 1) {
assembly {
return(0, 0)
}
}
} else {
// if the call was successful, skip the catch data
assembly {
currentOffset := add(currentOffset, catchCalldataLength)
}
}
return currentOffset;
}
function _deltaComposeInternal(
address callerAddress,
uint256 currentOffset,
uint256 calldataLength //
)
internal
virtual;
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;
import {BaseUtils} from "contracts/1delta/composer/generic/BaseUtils.sol";
/**
* @title Token transfer contract - should work across all EVMs - use Uniswap style Permit2
*/
contract AssetTransfers is BaseUtils {
// approval slot
bytes32 private constant CALL_MANAGEMENT_APPROVALS = 0x1aae13105d9b6581c36534caba5708726e5ea1e03175e823c989a5756966d1f3;
/// @notice fixed selector transferFrom(...) on permit2
bytes32 private constant PERMIT2_TRANSFER_FROM = 0x36c7851600000000000000000000000000000000000000000000000000000000;
/// @notice deterministically deployed pemrit2 address
address private constant PERMIT2 = 0x000000000022D473030F116dDEE9F6B43aC78BA3;
/*
* | Offset | Length (bytes) | Description |
* |--------|----------------|---------------------|
* | 0 | 20 | asset |
* | 20 | 20 | receiver |
* | 40 | 16 | amount |
*/
function _permit2TransferFrom(uint256 currentOffset, address callerAddress) internal returns (uint256) {
////////////////////////////////////////////////////
// Transfers tokens from caller to this address
// zero amount flags that the entire balance is sent
////////////////////////////////////////////////////
assembly {
let underlying := shr(96, calldataload(currentOffset))
let receiver := shr(96, calldataload(add(currentOffset, 20)))
let amount := shr(128, calldataload(add(currentOffset, 40)))
// when entering 0 as amount, use the callwe balance
if iszero(amount) {
// selector for balanceOf(address)
mstore(0, ERC20_BALANCE_OF)
// add this address as parameter
mstore(0x04, callerAddress)
// call to token
pop(
staticcall(
gas(),
underlying, // token
0x0,
0x24,
0x0,
0x20
)
)
// load the retrieved balance
amount := mload(0x0)
}
let ptr := mload(0x40)
mstore(ptr, PERMIT2_TRANSFER_FROM)
mstore(add(ptr, 0x04), callerAddress)
mstore(add(ptr, 0x24), receiver)
mstore(add(ptr, 0x44), amount)
mstore(add(ptr, 0x64), underlying)
if iszero(call(gas(), PERMIT2, 0, ptr, 0x84, 0x0, 0x0)) {
returndatacopy(0, 0, returndatasize())
revert(0, returndatasize())
}
currentOffset := add(currentOffset, 56)
}
return currentOffset;
}
/*
* | Offset | Length (bytes) | Description |
* |--------|----------------|---------------------|
* | 0 | 20 | asset |
* | 20 | 20 | receiver |
* | 40 | 16 | amount |
*/
function _transferFrom(uint256 currentOffset, address callerAddress) internal returns (uint256) {
////////////////////////////////////////////////////
// Transfers tokens from caller to this address
// zero amount flags that the entire balance is sent
////////////////////////////////////////////////////
assembly {
let underlying := shr(96, calldataload(currentOffset))
let receiver := shr(96, calldataload(add(currentOffset, 20)))
let amount := shr(128, calldataload(add(currentOffset, 40)))
// when entering 0 as amount, use the callwe balance
if iszero(amount) {
// selector for balanceOf(address)
mstore(0, ERC20_BALANCE_OF)
// add this address as parameter
mstore(0x04, callerAddress)
// call to token
pop(
staticcall(
gas(),
underlying, // token
0x0,
0x24,
0x0,
0x20
)
)
// load the retrieved balance
amount := mload(0x0)
}
let ptr := mload(0x40) // free memory pointer
// selector for transferFrom(address,address,uint256)
mstore(ptr, ERC20_TRANSFER_FROM)
mstore(add(ptr, 0x04), callerAddress)
mstore(add(ptr, 0x24), receiver)
mstore(add(ptr, 0x44), amount)
let success := call(gas(), underlying, 0, ptr, 0x64, ptr, 32)
let rdsize := returndatasize()
if iszero(
and(
success, // call itself succeeded
or(
iszero(rdsize), // no return data, or
and(
gt(rdsize, 31), // at least 32 bytes
eq(mload(ptr), 1) // starts with uint256(1)
)
)
)
) {
returndatacopy(0, 0, rdsize)
revert(0, rdsize)
}
currentOffset := add(currentOffset, 56)
}
return currentOffset;
}
/*
* | Offset | Length (bytes) | Description |
* |--------|----------------|---------------------|
* | 0 | 20 | asset |
* | 20 | 20 | receiver | <- use wrapped native here to wrap
* | 40 | 1 | config |
* | 41 | 16 | amount |
*/
function _sweep(uint256 currentOffset) internal returns (uint256) {
////////////////////////////////////////////////////
// Transfers either token or native balance from this
// contract to receiver. Reverts if minAmount is
// less than the contract balance
// config
// 0: sweep balance and validate against amount
// fetches the balance and checks balance >= amount
// 1: transfer amount to receiver, skip validation
////////////////////////////////////////////////////
assembly {
let underlying := shr(96, calldataload(currentOffset))
// we skip shr by loading the address to the lower bytes
let receiver := shr(96, calldataload(add(currentOffset, 20)))
// load so that amount is in the lower 14 bytes already
let providedAmount := calldataload(add(currentOffset, 25))
// load config
let config := and(UINT8_MASK, shr(128, providedAmount))
// mask amount
providedAmount := and(UINT128_MASK, providedAmount)
// initialize transferAmount
let transferAmount
// zero address is native
switch iszero(underlying)
////////////////////////////////////////////////////
// Transfer token
////////////////////////////////////////////////////
case 0 {
// for config = 0, the amount is the balance and we
// check that the balance is larger tha the amount provided
switch config
case 0 {
// selector for balanceOf(address)
mstore(0, ERC20_BALANCE_OF)
// add this address as parameter
mstore(0x04, address())
// call to token
pop(
staticcall(
gas(),
underlying,
0x0,
0x24,
0x0,
0x20 //
)
)
// load the retrieved balance
transferAmount := mload(0x0)
// revert if balance is not enough
if lt(transferAmount, providedAmount) {
mstore(0, SLIPPAGE)
revert(0, 0x4)
}
}
default { transferAmount := providedAmount }
if gt(transferAmount, 0) {
let ptr := mload(0x40) // free memory pointer
// selector for transfer(address,uint256)
mstore(ptr, ERC20_TRANSFER)
mstore(add(ptr, 0x04), receiver)
mstore(add(ptr, 0x24), transferAmount)
let success := call(gas(), underlying, 0, ptr, 0x44, ptr, 32)
let rdsize := returndatasize()
if iszero(
and(
success, // call itself succeeded
or(
iszero(rdsize), // no return data, or
and(
gt(rdsize, 31), // at least 32 bytes
eq(mload(ptr), 1) // starts with uint256(1)
)
)
)
) {
returndatacopy(0, 0, rdsize)
revert(0, rdsize)
}
}
}
////////////////////////////////////////////////////
// Transfer native
////////////////////////////////////////////////////
default {
switch config
case 0 {
transferAmount := selfbalance()
// revert if balance is not enough
if lt(transferAmount, providedAmount) {
mstore(0, SLIPPAGE)
revert(0, 0x4)
}
}
default { transferAmount := providedAmount }
if gt(transferAmount, 0) {
if iszero(
call(
gas(),
receiver,
transferAmount,
0x0, // input = empty for fallback/receive
0x0, // input size = zero
0x0, // output = empty
0x0 // output size = zero
)
) {
mstore(0, NATIVE_TRANSFER)
revert(0, 0x4) // revert when native transfer fails
}
}
}
currentOffset := add(currentOffset, 57)
}
return currentOffset;
}
/*
* | Offset | Length (bytes) | Description |
* |--------|----------------|----------------------|
* | 0 | 20 | token |
* | 20 | 20 | target |
*/
function _approve(uint256 currentOffset) internal returns (uint256) {
assembly {
// load underlying and target
let underlying := shr(96, calldataload(currentOffset))
let target := shr(96, calldataload(add(currentOffset, 20)))
// check whether the approval alderady was done
// if so, we can skip this part silently
mstore(0x0, underlying)
mstore(0x20, CALL_MANAGEMENT_APPROVALS)
mstore(0x20, keccak256(0x0, 0x40))
mstore(0x0, target)
let key := keccak256(0x0, 0x40)
// check if already approved
if iszero(sload(key)) {
let ptr := mload(0x40)
// selector for approve(address,uint256)
mstore(ptr, ERC20_APPROVE)
mstore(add(ptr, 0x04), target)
mstore(add(ptr, 0x24), MAX_UINT256)
pop(
call(
gas(),
underlying, //
0,
ptr,
0x44,
ptr,
32
)
)
sstore(key, 1)
}
currentOffset := add(currentOffset, 40)
}
return currentOffset;
}
/*
* | Offset | Length (bytes) | Description |
* |--------|----------------|---------------------|
* | 0 | 20 | wrappedNativeAddress|
* | 20 | 20 | receiver |
* | 40 | 1 | config |
* | 41 | 16 | amount |
*/
function _unwrap(uint256 currentOffset) internal virtual returns (uint256) {
////////////////////////////////////////////////////
// Transfers either token or native balance from this
// contract to receiver. Reverts if minAmount is
// less than the contract balance
// config
// 0: sweep balance and validate against amount
// fetches the balance and checks balance >= amount
// 1: transfer amount to receiver, skip validation
////////////////////////////////////////////////////
assembly {
// load receiver
let wrapperAsset := shr(96, calldataload(currentOffset))
// load receiver
let receiver := shr(96, calldataload(add(currentOffset, 20)))
// load so that amount is in the lower 14 bytes already
let providedAmount := calldataload(add(currentOffset, 25))
// load config
let config := and(UINT8_MASK, shr(128, providedAmount))
// mask amount
providedAmount := and(UINT128_MASK, providedAmount)
let transferAmount
// mask away the top bitmap
providedAmount := and(UINT120_MASK, providedAmount)
// validate if config is zero, otherwise skip
switch config
case 0 {
// selector for balanceOf(address)
mstore(0x0, ERC20_BALANCE_OF)
// add this address as parameter
mstore(0x4, address())
// call to underlying
pop(staticcall(gas(), wrapperAsset, 0x0, 0x24, 0x0, 0x20))
transferAmount := mload(0x0)
if lt(transferAmount, providedAmount) {
mstore(0, SLIPPAGE)
revert(0, 0x4)
}
}
default { transferAmount := providedAmount }
if gt(transferAmount, 0) {
// selector for withdraw(uint256)
mstore(0x0, 0x2e1a7d4d00000000000000000000000000000000000000000000000000000000)
mstore(0x4, transferAmount)
if iszero(
call(
gas(),
wrapperAsset,
0x0, // no ETH
0x0, // start of data
0x24, // input size = selector plus amount
0x0, // output = empty
0x0 // output size = zero
)
) {
// should only revert if receiver cannot receive native
mstore(0, NATIVE_TRANSFER)
revert(0, 0x4)
}
// transfer to receiver if different from this address
if xor(receiver, address()) {
// transfer native to receiver
if iszero(
call(
gas(),
receiver,
transferAmount,
0x0, // input = empty for fallback
0x0, // input size = zero
0x0, // output = empty
0x0 // output size = zero
)
) {
// should only revert if receiver cannot receive native
mstore(0, NATIVE_TRANSFER)
revert(0, 0x4)
}
}
}
currentOffset := add(currentOffset, 57)
}
return currentOffset;
}
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;
import {AssetTransfers} from "./AssetTransfers.sol";
import {TransferIds} from "../enums/DeltaEnums.sol";
/**
* @title Token transfer contract - should work across all EVMs - user Uniswap style Permit2
*/
contract Transfers is AssetTransfers {
function _transfers(uint256 currentOffset, address callerAddress) internal returns (uint256) {
uint256 transferOperation;
assembly {
let firstSlice := calldataload(currentOffset)
transferOperation := shr(248, firstSlice)
currentOffset := add(currentOffset, 1)
}
if (transferOperation == TransferIds.TRANSFER_FROM) {
return _transferFrom(currentOffset, callerAddress);
} else if (transferOperation == TransferIds.SWEEP) {
return _sweep(currentOffset);
} else if (transferOperation == TransferIds.UNWRAP_WNATIVE) {
return _unwrap(currentOffset);
} else if (transferOperation == TransferIds.PERMIT2_TRANSFER_FROM) {
return _permit2TransferFrom(currentOffset, callerAddress);
} else if (transferOperation == TransferIds.APPROVE) {
return _approve(currentOffset);
} else {
_invalidOperation();
}
}
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;
/**
* @title Raw error data holder contract
*/
abstract contract DeltaErrors {
////////////////////////////////////////////////////
// Error data
////////////////////////////////////////////////////
// the compiler should drop these since they are unused
// but it should still be included in the ABI to parse the
// errors below
error Slippage();
error NativeTransferFailed();
error WrapFailed();
error InvalidDex();
error BadPool();
error InvalidFlashLoan();
error InvalidOperation();
error InvalidCaller();
error InvalidInitiator();
error InvalidCalldata();
error Target();
error InvalidDexId();
// Slippage()
bytes4 internal constant SLIPPAGE = 0x7dd37f70;
// NativeTransferFailed()
bytes4 internal constant NATIVE_TRANSFER = 0xf4b3b1bc;
// WrapFailed()
bytes4 internal constant WRAP = 0xc30d93ce;
// InvalidDex()
bytes4 internal constant INVALID_DEX = 0x7948739e;
// BadPool()
bytes4 internal constant BAD_POOL = 0xb2c02722;
// InvalidFlashLoan()
bytes4 internal constant INVALID_FLASH_LOAN = 0xbafe1c53;
// InvalidOperation()
bytes4 internal constant INVALID_OPERATION = 0x398d4d32;
// InvalidCaller()
bytes4 internal constant INVALID_CALLER = 0x48f5c3ed;
// InvalidInitiator()
bytes4 internal constant INVALID_INITIATOR = 0xbfda1f28;
// InvalidCalldata()
bytes4 internal constant INVALID_CALLDATA = 0x8129bbcd;
// Target()
bytes4 internal constant INVALID_TARGET = 0x4fe6f55f;
// InvalidDexId()
bytes4 internal constant INVALID_DEX_ID = 0x0bbef348;
function _invalidOperation() internal pure {
assembly {
mstore(0, INVALID_OPERATION)
revert(0, 0x4)
}
}
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.28;
abstract contract Masks {
/// @dev Mask of lower 20 bytes.
uint256 internal constant ADDRESS_MASK = 0x00ffffffffffffffffffffffffffffffffffffffff;
/// @dev Mask of lower 1 byte.
uint256 internal constant UINT8_MASK = 0xff;
/// @dev Mask of lower 2 bytes.
uint256 internal constant UINT16_MASK = 0xffff;
/// @dev Mask of lower 3 bytes.
uint256 internal constant UINT24_MASK = 0xffffff;
/// @dev Mask of lower 4 bytes.
uint256 internal constant UINT32_MASK = 0xffffffff;
/// @dev Mask of lower 16 bytes.
uint256 internal constant UINT128_MASK = 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff;
/// @dev Mask of lower 15 bytes.
uint256 internal constant UINT120_MASK = 0x0000000000000000000000000000000000ffffffffffffffffffffffffffffff;
/// @dev MIN_SQRT_RATIO + 1 from Uniswap's TickMath
uint160 internal constant MIN_SQRT_RATIO = 4295128740;
/// @dev MAX_SQRT_RATIO - 1 from Uniswap's TickMath
uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970341;
/// @dev Maximum Uint256 value
uint256 internal constant MAX_UINT256 = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;
/// @dev Use this to distinguish FF upper bytes addresses and lower bytes addresses
uint256 internal constant FF_ADDRESS_COMPLEMENT = 0x000000000000000000000000000000000000000000ffffffffffffffffffffff;
/// @dev We use uint112-encoded amounts to typically fit one bit flag, one path length (uint16)
/// add 2 amounts (2xuint112) into 32bytes, as such we use this mask for extracting those
uint256 internal constant UINT112_MASK = 0x000000000000000000000000000000000000ffffffffffffffffffffffffffff;
/// @dev Mask for Is Native
uint256 internal constant NATIVE_FLAG = 1 << 127;
/// @dev Mask for shares
uint256 internal constant USE_SHARES_FLAG = 1 << 126;
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;
abstract contract ERC20Selectors {
////////////////////////////////////////////////////
// ERC20 selectors
////////////////////////////////////////////////////
/// @dev selector for approve(address,uint256)
bytes32 internal constant ERC20_APPROVE = 0x095ea7b300000000000000000000000000000000000000000000000000000000;
/// @dev selector for transferFrom(address,address,uint256)
bytes32 internal constant ERC20_TRANSFER_FROM = 0x23b872dd00000000000000000000000000000000000000000000000000000000;
/// @dev selector for transfer(address,uint256)
bytes32 internal constant ERC20_TRANSFER = 0xa9059cbb00000000000000000000000000000000000000000000000000000000;
/// @dev selector for allowance(address,address)
bytes32 internal constant ERC20_ALLOWANCE = 0xdd62ed3e00000000000000000000000000000000000000000000000000000000;
/// @dev selector for balanceOf(address)
bytes32 internal constant ERC20_BALANCE_OF = 0x70a0823100000000000000000000000000000000000000000000000000000000;
}{
"optimizer": {
"enabled": true,
"runs": 1000000
},
"evmVersion": "paris",
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"name":"BadPool","type":"error"},{"inputs":[],"name":"BridgeFailed","type":"error"},{"inputs":[],"name":"InsufficientAmount","type":"error"},{"inputs":[],"name":"InsufficientValue","type":"error"},{"inputs":[{"internalType":"uint16","name":"assetId","type":"uint16"}],"name":"InvalidAssetId","type":"error"},{"inputs":[],"name":"InvalidCalldata","type":"error"},{"inputs":[],"name":"InvalidCaller","type":"error"},{"inputs":[],"name":"InvalidDestination","type":"error"},{"inputs":[],"name":"InvalidDex","type":"error"},{"inputs":[],"name":"InvalidDexId","type":"error"},{"inputs":[],"name":"InvalidFlashLoan","type":"error"},{"inputs":[],"name":"InvalidInitiator","type":"error"},{"inputs":[],"name":"InvalidOperation","type":"error"},{"inputs":[],"name":"InvalidReceiver","type":"error"},{"inputs":[],"name":"NativeTransferFailed","type":"error"},{"inputs":[],"name":"Slippage","type":"error"},{"inputs":[{"internalType":"uint256","name":"expected","type":"uint256"},{"internalType":"uint256","name":"actual","type":"uint256"}],"name":"SlippageTooHigh","type":"error"},{"inputs":[],"name":"Target","type":"error"},{"inputs":[],"name":"WrapFailed","type":"error"},{"inputs":[],"name":"ZeroBalance","type":"error"},{"inputs":[{"internalType":"bytes","name":"","type":"bytes"}],"name":"deltaForwardCompose","outputs":[],"stateMutability":"payable","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
6080604052348015600f57600080fd5b506115bd8061001f6000396000f3fe6080604052600436106100225760003560e01c80636a0c90ff1461002e57600080fd5b3661002957005b600080fd5b61004161003c3660046114d9565b610043565b005b604460243581013361005681848461005d565b5050505050565b60018201913560f81c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0810161009d576100968361012c565b92506100da565b602181036100af57610096838561025d565b604081036100c15761009683856103f8565b609081036100d2576100968361046f565b6100da6104d1565b8183106100e757506100ed565b5061005d565b80821115610127576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b6000813560601c6e22d473030f116ddee9f6b43ac78ba38103610173577fee90c4680000000000000000000000000000000000000000000000000000000060005260046000fd5b6026830192601481013560801c906024013560f01c6f80000000000000000000000000000000821680156101a9574792506101be565b6effffffffffffffffffffffffffffff831692505b506040517f23b872dd0000000000000000000000000000000000000000000000000000000086357fffffffff000000000000000000000000000000000000000000000000000000001603610236577fee90c4680000000000000000000000000000000000000000000000000000000060005260046000fd5b81868237600080838386885af1610251573d6000803e3d6000fd5b50939093019392505050565b600080600080853560601c6e22d473030f116ddee9f6b43ac78ba381036102a8577fee90c4680000000000000000000000000000000000000000000000000000000060005260046000fd5b6026870196601481013560801c906024013560f01c6f80000000000000000000000000000000821680156102de574792506102f3565b6effffffffffffffffffffffffffffff831692505b506040517f23b872dd000000000000000000000000000000000000000000000000000000008a357fffffffff00000000000000000000000000000000000000000000000000000000160361036b577fee90c4680000000000000000000000000000000000000000000000000000000060005260046000fd5b818a8237600080838386885af1965050808901985050505085358060f81c925083158315161561039f573d6000803e3d6000fd5b8060e81c61ffff16915050600386019550826103e65780156103d75760006103c7828861154d565b90506103d486888361005d565b95505b816001036103e157005b6103eb565b948501945b8593505050505b92915050565b60018201916000903560f81c8061041b5761041384846104fb565b9150506103f2565b6001810361042c57610413846105c5565b6003810361043d576104138461077a565b6004810361044f5761041384846108db565b600581036104605761041384610996565b6104686104d1565b5092915050565b60018101906000903560f81c806104905761048983610a56565b9392505050565b600a81036104a15761048983610da8565b601481036104b25761048983611146565b601e81036104c3576104898361116f565b6104cb6104d1565b50919050565b7f398d4d320000000000000000000000000000000000000000000000000000000060005260046000fd5b6000823560601c601484013560601c602885013560801c80610550577f70a0823100000000000000000000000000000000000000000000000000000000600052846004526020600060246000865afa50506000515b6040517f23b872dd0000000000000000000000000000000000000000000000000000000081528560048201528260248201528160448201526020816064836000885af193503d92506001815114601f84111683151784166105b557826000803e826000fd5b5050506038939093019392505050565b6000813560601c601483013560601c60198401358060801c60ff16816fffffffffffffffffffffffffffffffff16915060008415600081146106895782801561061057849250610645565b47925084831015610645577f7dd37f700000000000000000000000000000000000000000000000000000000060005260046000fd5b5081156106845760008060008085895af1610684577ff4b3b1bc0000000000000000000000000000000000000000000000000000000060005260046000fd5b610769565b82801561069857849250610703565b7f70a08231000000000000000000000000000000000000000000000000000000006000523060045260206000602460008a5afa50600051925084831015610703577f7dd37f700000000000000000000000000000000000000000000000000000000060005260046000fd5b508115610769576040517fa9059cbb00000000000000000000000000000000000000000000000000000000815285600482015282602482015260208160448360008b5af13d6001835114601f821116811517821661076557806000803e806000fd5b5050505b505050603994909401949350505050565b60008135606090811c906014840135901c60198401356effffffffffffffffffffffffffffff81169060801c60ff16848180156107b957839150610824565b7f70a0823100000000000000000000000000000000000000000000000000000000600052306004526020600060246000895afa50600051915083821015610824577f7dd37f700000000000000000000000000000000000000000000000000000000060005260046000fd5b5080156108cb577f2e1a7d4d00000000000000000000000000000000000000000000000000000000600052806004526000806024600080895af161088c577ff4b3b1bc0000000000000000000000000000000000000000000000000000000060005260046000fd5b3084146108cb5760008060008084885af16108cb577ff4b3b1bc0000000000000000000000000000000000000000000000000000000060005260046000fd5b5050506039939093019392505050565b6000823560601c601484013560601c602885013560801c80610930577f70a0823100000000000000000000000000000000000000000000000000000000600052846004526020600060246000865afa50506000515b6040517f36c7851600000000000000000000000000000000000000000000000000000000815285600482015282602482015281604482015283606482015260008060848360006e22d473030f116ddee9f6b43ac78ba35af16105b5573d6000803e3d6000fd5b6000813560601c601483013560601c816000527f1aae13105d9b6581c36534caba5708726e5ea1e03175e823c989a5756966d1f360205260406000206020528060005260406000208054610a48576040517f095ea7b30000000000000000000000000000000000000000000000000000000081528260048201527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60248201526020816044836000885af15050600181555b505050602891909101919050565b6000610aa2565b8060005260046000fd5b7f70a0823100000000000000000000000000000000000000000000000000000000600052306004526020600060246000845afa505060005190565b8135606090811c90608584013560f090811c91608786013590911c90850135608090811c7fffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffff811691600091607489013590911c9082906f800000000000000000000000000000001647851560018114610b6157828015610b26578588019650610b2a565b8596505b5081861115610b5c57610b5c7f1101129400000000000000000000000000000000000000000000000000000000610a5d565b610bb6565b828015610b75578583039750829650610bb4565b610b7e8b610a67565b975085965082871115610bb457610bb47f1101129400000000000000000000000000000000000000000000000000000000610a5d565b505b505050633b9aca0060708a013560e01c633b9aca0003850204905060405196507fcbef2aa90000000000000000000000000000000000000000000000000000000087526080600488015281602488015260006044880152604c89013560601c6064880152602889013560e01c6084880152602c89013560a48801528360c48801528060e4880152505060e061010486015260009150821560018114610c60578015610c6a57610c9f565b6101209250610c9f565b6020840460208506600080821160018114610c8757839150610c8e565b6001840191505b506001810160200260e00195505050505b50816101248601526000841560018114610ceb576020860460208706600080821160018114610cd057839150610cd7565b6001840191505b506001810160200287019450505050610cf2565b6020840191505b50610144860181905261016486018481528415610d1657848660898b010160208301375b50918501608401848152918415610d3257846089890160208501375b60009250850160849081019088013560f81c1560018114610d655760208252600060208301528660408301039350610d72565b6000825286602083010393505b505081850160405260008083878460148c013560601c5af1610d98573d6000803e3d6000fd5b5050930190920160890192915050565b6000602882013560601c605c83013560801c7fffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffff8116906f800000000000000000000000000000001660aa85013560f01c84831560018114610e44578315610e3f5747851115610e3b577f110112940000000000000000000000000000000000000000000000000000000060005260046000fd5b8491505b610e92565b838015610e5657479550859250610e90565b7f70a08231000000000000000000000000000000000000000000000000000000006000523060045260206000602460008a5afa5060005195505b505b50606c87013560801c925082841160018114610ed2577f5945ea560000000000000000000000000000000000000000000000000000000060005260046000fd5b9284039250608487013560f881901c9060f01c60ff1681810360006001848414610fac5760ff83901d8084180380600c8114610f5857600b8114610f6557600a8114610f725760098114610f7f5760088114610f8b5760078114610f975760068114610fa25760005b82811015610f5257600a9390930292600101610f3b565b50610fa9565b64e8d4a510009250610fa9565b64174876e8009250610fa9565b6402540be4009250610fa9565b633b9aca009250610fa9565b6305f5e1009250610fa9565b629896809250610fa9565b620f424092505b50505b84841060018114610fd45797810297633b9aca00607c8e013560e01c8b028302049250610fee565b81633b9aca0002607c8e013560e01c8b0204925081890498505b505080871160018114611025577f5945ea560000000000000000000000000000000000000000000000000000000060005260046000fd5b908703905060405196507fad5425c600000000000000000000000000000000000000000000000000000000875260148b013560601c600488015260868b01356024880152886044880152603c8b013560648801528760848801528060a488015250505050608087013560e01c60c4840152600060e48401524261010484015260a687013560e01c6101248401526000610144840152610180610164840152816101848401526000821160018114611100576000806101a486858c3560601c5af16110f3573d6000803e3d6000fd5b6101a48401604052611135565b8260ac89016101a4860137600080846101a40186858c3560601c5af161112a573d6000803e3d6000fd5b826101c40184016040525b50509490940160ac01949350505050565b60288101906000908035606090811c9160140135901c61116782828661127d565b949350505050565b6000813560601c6014830135603484013560801c60448501356064860195508115600181036111c957479250826111c9576111c97f669567ea00000000000000000000000000000000000000000000000000000000610a5d565b504681036111fa576111fa7fac6b05f500000000000000000000000000000000000000000000000000000000610a5d565b82611228576112287f1e4ec46b00000000000000000000000000000000000000000000000000000000610a5d565b6040517fc9630cb000000000000000000000000000000000000000000000000000000000815281600482015283602482015260008060448386895af1611272573d6000803e3d6000fd5b509495945050505050565b6000604051905081358060f01c8160101b60f01c8260201b60f01c8360301b60f01c8460401b60801c9450601887013560801c478111156112e2577f110112940000000000000000000000000000000000000000000000000000000060005260046000fd5b60288801358060581c60ff168160601c91508760008114611308578860808b0152611345565b7f70a08231000000000000000000000000000000000000000000000000000000006000523060045260206000602460008f5afa5060005160808b01525b5086895260208901869052604089018590526060890184905260a089019290925260c0880181905260e08089018390527f2147796000000000000000000000000000000000000000000000000000000000610100808b01919091526101048a0182815260808b01516101248c0152601f9889017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09081169283016101448d01819052988a0181169092016101208101610164808e01829052988b018416808301610140016101848f018190526101a48f01979097526101c48e0197909752603d9d909d019c939a509798929793969290950116909201010190611461565b60008382018351808252808760208401379590950195945050505050565b61146d88878984611443565b975061147e888660208a0184611443565b975061148f888560408a0184611443565b97506114a0888460608a0184611443565b9750508061010087010160405260008082610100890160a08a01518d5af16114cc573d6000803e3d6000fd5b5094979650505050505050565b600080602083850312156114ec57600080fd5b823567ffffffffffffffff81111561150357600080fd5b8301601f8101851361151457600080fd5b803567ffffffffffffffff81111561152b57600080fd5b85602082840101111561153d57600080fd5b6020919091019590945092505050565b808201808211156103f2577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fdfea264697066735822122027294167b7006c7aef9b0238bcddf1a1d540bf2131f293e4e53fcf24a87fb9f364736f6c634300081c0033
Deployed Bytecode
0x6080604052600436106100225760003560e01c80636a0c90ff1461002e57600080fd5b3661002957005b600080fd5b61004161003c3660046114d9565b610043565b005b604460243581013361005681848461005d565b5050505050565b60018201913560f81c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0810161009d576100968361012c565b92506100da565b602181036100af57610096838561025d565b604081036100c15761009683856103f8565b609081036100d2576100968361046f565b6100da6104d1565b8183106100e757506100ed565b5061005d565b80821115610127576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b6000813560601c6e22d473030f116ddee9f6b43ac78ba38103610173577fee90c4680000000000000000000000000000000000000000000000000000000060005260046000fd5b6026830192601481013560801c906024013560f01c6f80000000000000000000000000000000821680156101a9574792506101be565b6effffffffffffffffffffffffffffff831692505b506040517f23b872dd0000000000000000000000000000000000000000000000000000000086357fffffffff000000000000000000000000000000000000000000000000000000001603610236577fee90c4680000000000000000000000000000000000000000000000000000000060005260046000fd5b81868237600080838386885af1610251573d6000803e3d6000fd5b50939093019392505050565b600080600080853560601c6e22d473030f116ddee9f6b43ac78ba381036102a8577fee90c4680000000000000000000000000000000000000000000000000000000060005260046000fd5b6026870196601481013560801c906024013560f01c6f80000000000000000000000000000000821680156102de574792506102f3565b6effffffffffffffffffffffffffffff831692505b506040517f23b872dd000000000000000000000000000000000000000000000000000000008a357fffffffff00000000000000000000000000000000000000000000000000000000160361036b577fee90c4680000000000000000000000000000000000000000000000000000000060005260046000fd5b818a8237600080838386885af1965050808901985050505085358060f81c925083158315161561039f573d6000803e3d6000fd5b8060e81c61ffff16915050600386019550826103e65780156103d75760006103c7828861154d565b90506103d486888361005d565b95505b816001036103e157005b6103eb565b948501945b8593505050505b92915050565b60018201916000903560f81c8061041b5761041384846104fb565b9150506103f2565b6001810361042c57610413846105c5565b6003810361043d576104138461077a565b6004810361044f5761041384846108db565b600581036104605761041384610996565b6104686104d1565b5092915050565b60018101906000903560f81c806104905761048983610a56565b9392505050565b600a81036104a15761048983610da8565b601481036104b25761048983611146565b601e81036104c3576104898361116f565b6104cb6104d1565b50919050565b7f398d4d320000000000000000000000000000000000000000000000000000000060005260046000fd5b6000823560601c601484013560601c602885013560801c80610550577f70a0823100000000000000000000000000000000000000000000000000000000600052846004526020600060246000865afa50506000515b6040517f23b872dd0000000000000000000000000000000000000000000000000000000081528560048201528260248201528160448201526020816064836000885af193503d92506001815114601f84111683151784166105b557826000803e826000fd5b5050506038939093019392505050565b6000813560601c601483013560601c60198401358060801c60ff16816fffffffffffffffffffffffffffffffff16915060008415600081146106895782801561061057849250610645565b47925084831015610645577f7dd37f700000000000000000000000000000000000000000000000000000000060005260046000fd5b5081156106845760008060008085895af1610684577ff4b3b1bc0000000000000000000000000000000000000000000000000000000060005260046000fd5b610769565b82801561069857849250610703565b7f70a08231000000000000000000000000000000000000000000000000000000006000523060045260206000602460008a5afa50600051925084831015610703577f7dd37f700000000000000000000000000000000000000000000000000000000060005260046000fd5b508115610769576040517fa9059cbb00000000000000000000000000000000000000000000000000000000815285600482015282602482015260208160448360008b5af13d6001835114601f821116811517821661076557806000803e806000fd5b5050505b505050603994909401949350505050565b60008135606090811c906014840135901c60198401356effffffffffffffffffffffffffffff81169060801c60ff16848180156107b957839150610824565b7f70a0823100000000000000000000000000000000000000000000000000000000600052306004526020600060246000895afa50600051915083821015610824577f7dd37f700000000000000000000000000000000000000000000000000000000060005260046000fd5b5080156108cb577f2e1a7d4d00000000000000000000000000000000000000000000000000000000600052806004526000806024600080895af161088c577ff4b3b1bc0000000000000000000000000000000000000000000000000000000060005260046000fd5b3084146108cb5760008060008084885af16108cb577ff4b3b1bc0000000000000000000000000000000000000000000000000000000060005260046000fd5b5050506039939093019392505050565b6000823560601c601484013560601c602885013560801c80610930577f70a0823100000000000000000000000000000000000000000000000000000000600052846004526020600060246000865afa50506000515b6040517f36c7851600000000000000000000000000000000000000000000000000000000815285600482015282602482015281604482015283606482015260008060848360006e22d473030f116ddee9f6b43ac78ba35af16105b5573d6000803e3d6000fd5b6000813560601c601483013560601c816000527f1aae13105d9b6581c36534caba5708726e5ea1e03175e823c989a5756966d1f360205260406000206020528060005260406000208054610a48576040517f095ea7b30000000000000000000000000000000000000000000000000000000081528260048201527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60248201526020816044836000885af15050600181555b505050602891909101919050565b6000610aa2565b8060005260046000fd5b7f70a0823100000000000000000000000000000000000000000000000000000000600052306004526020600060246000845afa505060005190565b8135606090811c90608584013560f090811c91608786013590911c90850135608090811c7fffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffff811691600091607489013590911c9082906f800000000000000000000000000000001647851560018114610b6157828015610b26578588019650610b2a565b8596505b5081861115610b5c57610b5c7f1101129400000000000000000000000000000000000000000000000000000000610a5d565b610bb6565b828015610b75578583039750829650610bb4565b610b7e8b610a67565b975085965082871115610bb457610bb47f1101129400000000000000000000000000000000000000000000000000000000610a5d565b505b505050633b9aca0060708a013560e01c633b9aca0003850204905060405196507fcbef2aa90000000000000000000000000000000000000000000000000000000087526080600488015281602488015260006044880152604c89013560601c6064880152602889013560e01c6084880152602c89013560a48801528360c48801528060e4880152505060e061010486015260009150821560018114610c60578015610c6a57610c9f565b6101209250610c9f565b6020840460208506600080821160018114610c8757839150610c8e565b6001840191505b506001810160200260e00195505050505b50816101248601526000841560018114610ceb576020860460208706600080821160018114610cd057839150610cd7565b6001840191505b506001810160200287019450505050610cf2565b6020840191505b50610144860181905261016486018481528415610d1657848660898b010160208301375b50918501608401848152918415610d3257846089890160208501375b60009250850160849081019088013560f81c1560018114610d655760208252600060208301528660408301039350610d72565b6000825286602083010393505b505081850160405260008083878460148c013560601c5af1610d98573d6000803e3d6000fd5b5050930190920160890192915050565b6000602882013560601c605c83013560801c7fffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffff8116906f800000000000000000000000000000001660aa85013560f01c84831560018114610e44578315610e3f5747851115610e3b577f110112940000000000000000000000000000000000000000000000000000000060005260046000fd5b8491505b610e92565b838015610e5657479550859250610e90565b7f70a08231000000000000000000000000000000000000000000000000000000006000523060045260206000602460008a5afa5060005195505b505b50606c87013560801c925082841160018114610ed2577f5945ea560000000000000000000000000000000000000000000000000000000060005260046000fd5b9284039250608487013560f881901c9060f01c60ff1681810360006001848414610fac5760ff83901d8084180380600c8114610f5857600b8114610f6557600a8114610f725760098114610f7f5760088114610f8b5760078114610f975760068114610fa25760005b82811015610f5257600a9390930292600101610f3b565b50610fa9565b64e8d4a510009250610fa9565b64174876e8009250610fa9565b6402540be4009250610fa9565b633b9aca009250610fa9565b6305f5e1009250610fa9565b629896809250610fa9565b620f424092505b50505b84841060018114610fd45797810297633b9aca00607c8e013560e01c8b028302049250610fee565b81633b9aca0002607c8e013560e01c8b0204925081890498505b505080871160018114611025577f5945ea560000000000000000000000000000000000000000000000000000000060005260046000fd5b908703905060405196507fad5425c600000000000000000000000000000000000000000000000000000000875260148b013560601c600488015260868b01356024880152886044880152603c8b013560648801528760848801528060a488015250505050608087013560e01c60c4840152600060e48401524261010484015260a687013560e01c6101248401526000610144840152610180610164840152816101848401526000821160018114611100576000806101a486858c3560601c5af16110f3573d6000803e3d6000fd5b6101a48401604052611135565b8260ac89016101a4860137600080846101a40186858c3560601c5af161112a573d6000803e3d6000fd5b826101c40184016040525b50509490940160ac01949350505050565b60288101906000908035606090811c9160140135901c61116782828661127d565b949350505050565b6000813560601c6014830135603484013560801c60448501356064860195508115600181036111c957479250826111c9576111c97f669567ea00000000000000000000000000000000000000000000000000000000610a5d565b504681036111fa576111fa7fac6b05f500000000000000000000000000000000000000000000000000000000610a5d565b82611228576112287f1e4ec46b00000000000000000000000000000000000000000000000000000000610a5d565b6040517fc9630cb000000000000000000000000000000000000000000000000000000000815281600482015283602482015260008060448386895af1611272573d6000803e3d6000fd5b509495945050505050565b6000604051905081358060f01c8160101b60f01c8260201b60f01c8360301b60f01c8460401b60801c9450601887013560801c478111156112e2577f110112940000000000000000000000000000000000000000000000000000000060005260046000fd5b60288801358060581c60ff168160601c91508760008114611308578860808b0152611345565b7f70a08231000000000000000000000000000000000000000000000000000000006000523060045260206000602460008f5afa5060005160808b01525b5086895260208901869052604089018590526060890184905260a089019290925260c0880181905260e08089018390527f2147796000000000000000000000000000000000000000000000000000000000610100808b01919091526101048a0182815260808b01516101248c0152601f9889017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09081169283016101448d01819052988a0181169092016101208101610164808e01829052988b018416808301610140016101848f018190526101a48f01979097526101c48e0197909752603d9d909d019c939a509798929793969290950116909201010190611461565b60008382018351808252808760208401379590950195945050505050565b61146d88878984611443565b975061147e888660208a0184611443565b975061148f888560408a0184611443565b97506114a0888460608a0184611443565b9750508061010087010160405260008082610100890160a08a01518d5af16114cc573d6000803e3d6000fd5b5094979650505050505050565b600080602083850312156114ec57600080fd5b823567ffffffffffffffff81111561150357600080fd5b8301601f8101851361151457600080fd5b803567ffffffffffffffff81111561152b57600080fd5b85602082840101111561153d57600080fd5b6020919091019590945092505050565b808201808211156103f2577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fdfea264697066735822122027294167b7006c7aef9b0238bcddf1a1d540bf2131f293e4e53fcf24a87fb9f364736f6c634300081c0033
Loading...
Loading
Loading...
Loading
Loading...
Loading
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.