Source Code
Overview
S Balance
More Info
ContractCreator
Multichain Info
N/A
| Transaction Hash |
Method
|
Block
|
From
|
To
|
Amount
|
||||
|---|---|---|---|---|---|---|---|---|---|
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
Intents
Compiler Version
v0.8.28+commit.7893614a
Optimization Enabled:
Yes with 200 runs
Other Settings:
prague EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;
import 'forge-std/console.sol';
import '@openzeppelin-upgradeable/proxy/utils/Initializable.sol';
import '@openzeppelin-upgradeable/access/Ownable2StepUpgradeable.sol';
import '@openzeppelin-upgradeable/proxy/utils/UUPSUpgradeable.sol';
import '@openzeppelin-upgradeable/utils/ReentrancyGuardUpgradeable.sol';
import '@openzeppelin/token/ERC20/IERC20.sol';
import '@openzeppelin/token/ERC20/utils/SafeERC20.sol';
import '@contracts/assetManager/AssetManager.sol';
import '@contracts/wallet/WalletFactory.sol';
import './IntentErrors.sol';
import {FillLib, Fill, FillResponse} from './FillLib.sol';
import {IntentDataLib, FeeData, IntentData} from './IntentDataLib.sol';
import {IIntentHooks} from './IIntentHooks.sol';
import '@contracts/utils/FeeM.sol';
contract Intents is Initializable, Ownable2StepUpgradeable, UUPSUpgradeable, ReentrancyGuardUpgradeable, FeeM {
using SafeERC20 for IERC20;
using AddressLib for address;
using AddressLib for bytes;
using FillLib for Fill;
using FillLib for bytes;
using IntentDataLib for Intent;
address public constant NATIVE_TOKEN = address(0);
struct Intent {
uint256 intentId;
address creator;
address inputToken;
address outputToken;
uint256 inputAmount;
uint256 minOutputAmount;
uint256 deadline; // Optional: 0 means no deadline
bool allowPartialFill; // Whether partial fills are allowed
uint256 srcChain; // Source chain ID
uint256 dstChain; // Destination chain ID
bytes srcAddress; // Source address in bytes (for cross-chain)
bytes dstAddress; // Destination address in bytes (for cross-chain)
address solver; // Solver address
bytes data; // Arbitrary data for the intent
}
struct IntentState {
bool exists;
uint256 remainingInput;
uint256 receivedOutput;
bool pendingPayment;
}
struct PendingIntentState {
uint256 pendingInput;
uint256 pendingOutput;
}
struct ExternalFill {
bytes32 intentHash;
address to;
address token;
uint256 inputAmount;
uint256 outputAmount;
}
struct Payout {
address solver;
uint256 amount;
}
IWalletFactory public walletFactory;
IAssetManager public assetManager;
IConnection public connection;
uint256 public HUB_CHAIN_ID;
mapping(bytes32 => IntentState) public intentStates;
mapping(uint256 => ExternalFill) public externalFills;
mapping(uint256 => bytes) public spokes;
mapping(address => bool) public whitelistedSolvers;
mapping(bytes32 => PendingIntentState) public pendingIntentStates;
mapping(bytes32 => Payout[]) public pendingPayouts;
mapping(bytes32 => FeeData) public partnerFee;
/// @custom:oz-upgrades-unsafe-allow constructor
constructor() {
_disableInitializers();
}
function initialize(
IWalletFactory _walletFactory,
IAssetManager _assetManager,
IConnection _connection,
uint256 _HUB_CHAIN_ID
) public initializer {
__Ownable_init(msg.sender);
__UUPSUpgradeable_init();
walletFactory = _walletFactory;
assetManager = _assetManager;
connection = _connection;
HUB_CHAIN_ID = _HUB_CHAIN_ID;
}
/// @dev Required by the OZ UUPS module
function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}
function getImplementation() external view returns (address) {
return ERC1967Utils.getImplementation();
}
event IntentCreated(
bytes32 intentHash,
Intent intent
);
event IntentFilled(
bytes32 intentHash,
IntentState intentState
);
event IntentCancelled(
bytes32 intentHash
);
event ExternalFillFailed(
uint256 fillId,
ExternalFill fill
);
function addSpoke(
uint256 chainID,
bytes memory spokeAddress
) external onlyOwner {
spokes[chainID] = spokeAddress;
}
function setWhitelistedSolver(
address solver,
bool whitelisted
) external onlyOwner {
whitelistedSolvers[solver] = whitelisted;
}
/// @notice Creates a new intent
/// @param intent The intent details
/// @dev Transfers input tokens from sender to this contract or directly to solver
function createIntent(Intent calldata intent) external payable nonReentrant {
bytes32 intentHash = keccak256(abi.encode(intent));
IntentData memory data = intent.getData();
if (data.hookData.hook != address(0)) {
require(intent.creator == msg.sender, "Creator must be sender");
require(intent.inputToken != NATIVE_TOKEN, "Native token cannot be used as input token with hooks");
IIntentHooks(data.hookData.hook).onCreateIntent(intent);
} else {
uint256 fee = data.feeData.fee;
transferFrom(intent.inputToken, intent.inputAmount + fee);
}
IntentState memory state = intentStates[intentHash];
if (!state.exists) {
state = IntentState({
exists: true,
remainingInput: intent.inputAmount,
receivedOutput: 0,
pendingPayment: false
});
} else if (state.pendingPayment) {
processPendingPayouts(intentHash, intent.inputToken);
state.pendingPayment = false;
} else {
revert IntentAlreadyExists();
}
emit IntentCreated(intentHash, intent);
if (state.remainingInput == 0) {
delete intentStates[intentHash];
} else {
intentStates[intentHash] = state;
}
}
function canCancelHook(Intent calldata intent, IntentState memory state) internal view returns (bool) {
IntentData memory data = intent.getData();
address hook = data.hookData.hook;
if (msg.sender != intent.creator && (intent.deadline == 0 || block.timestamp <= intent.deadline)) {
if (hook != address(0)) {
uint256 remainingInputWithFee = state.remainingInput + intent.calculateFee(state, state.remainingInput);
return IIntentHooks(hook).isCancellable(intent, state, remainingInputWithFee);
}
}
return false;
}
function cancelIntent(Intent calldata intent) external nonReentrant {
bytes32 intentHash = keccak256(abi.encode(intent));
IntentState storage state = intentStates[intentHash];
PendingIntentState storage pendingState = pendingIntentStates[intentHash];
if (state.remainingInput == 0) revert IntentNotFound();
if (pendingState.pendingOutput > 0) revert PendingFillExists();
if (msg.sender != intent.creator &&
(intent.deadline == 0 || block.timestamp <= intent.deadline) &&
!canCancelHook(intent, state)) {
revert Unauthorized();
}
if (state.remainingInput > 0) {
IntentData memory data = intent.getData();
// Calculate earned fees based on filled amount
uint256 filledAmount = intent.inputAmount - state.remainingInput;
uint256 earnedFees = 0;
if (data.feeData.receiver != address(0) && data.feeData.fee > 0) {
earnedFees = (data.feeData.fee * filledAmount) / intent.inputAmount;
}
// Send earned fees to fee receiver
if (earnedFees > 0) {
transferToken(intent.inputToken, data.feeData.receiver, earnedFees);
}
// Calculate remaining fee to return to creator
uint256 remainingFee = data.feeData.fee - earnedFees;
uint256 repayAmount = state.remainingInput + remainingFee;
delete partnerFee[intentHash];
if (data.hookData.hook != address(0)) {
IIntentHooks(data.hookData.hook).onCancelIntent(intent, repayAmount);
} else {
sendToken(intent.inputToken, intent.srcChain, intent.srcAddress, repayAmount);
}
}
delete intentStates[intentHash];
emit IntentCancelled(intentHash);
}
function preFillIntent(
Intent calldata intent,
uint256 _inputAmount,
uint256 _outputAmount,
uint256 _externalFillId
) external payable nonReentrant {
bytes32 intentHash = keccak256(abi.encode(intent));
IntentState storage state = intentStates[intentHash];
require(intent.getData().hookData.hook == address(0), "Hooks are not allowed to be pre-filled");
if (!state.exists) {
intentStates[intentHash] = IntentState({
exists: true,
remainingInput: intent.inputAmount,
receivedOutput: 0,
pendingPayment: true
});
}
internalFill(intent, intentHash, _inputAmount, _outputAmount, _externalFillId);
}
/// @notice Fills an intent either partially or fully
/// @param intent The intent to fill
/// @param _inputAmount Amount of input tokens to fill
/// @param _outputAmount Amount of output tokens provided
/// @param _externalFillId ID for cross-chain fills (0 for same-chain fills)
function fillIntent(
Intent calldata intent,
uint256 _inputAmount,
uint256 _outputAmount,
uint256 _externalFillId
) external payable nonReentrant {
bytes32 intentHash = keccak256(abi.encode(intent));
IntentState storage state = intentStates[intentHash];
if (!state.exists) revert IntentNotFound();
if (state.pendingPayment) revert IntentNotFound();
internalFill(intent, intentHash, _inputAmount, _outputAmount, _externalFillId);
}
function fillIntentTest(
bytes32 intentHash,
bytes memory spokeTokenAddress,
uint256 _outputAmount,
uint256 _externalFillId,
bytes memory dstAddress,
uint256 dstChain
) external payable {
bytes memory filler = spokes[dstChain];
Fill memory fill = Fill({
fillID: _externalFillId,
intentHash: abi.encode(intentHash),
solver: msg.sender.toBytes(),
receiver: dstAddress,
token: spokeTokenAddress,
amount: _outputAmount
});
connection.sendMessage(dstChain, filler, fill.encode());
}
function internalFill(
Intent calldata intent,
bytes32 intentHash,
uint256 _inputAmount,
uint256 _outputAmount,
uint256 _externalFillId
) internal {
IntentState storage state = intentStates[intentHash];
PendingIntentState storage pendingState = pendingIntentStates[intentHash];
FeeData memory feeData = intent.getData().feeData;
if (!state.exists) revert IntentNotFound();
uint256 remainingInput = state.remainingInput - pendingState.pendingInput;
if (_inputAmount > remainingInput) revert InvalidAmount();
if (_inputAmount < remainingInput && !intent.allowPartialFill) revert PartialFillNotAllowed();
if (intent.solver != address(0) && intent.solver != msg.sender) revert InvalidSolver();
uint256 minOutputForFill = (_inputAmount * intent.minOutputAmount) / intent.inputAmount;
if (_outputAmount < minOutputForFill) revert InvalidAmount();
IntentData memory data = intent.getData();
if (_externalFillId != 0) {
_externalFill(intent, intentHash, _inputAmount, _outputAmount, _externalFillId, data);
return;
}
transferFrom(intent.outputToken, _outputAmount);
sendToken(intent.outputToken, intent.dstChain, intent.dstAddress, _outputAmount);
if (data.hookData.hook != address(0)) {
require(!state.pendingPayment, "Cannot prefill hooks");
uint256 fee = intent.calculateFee(state, _inputAmount);
IIntentHooks(data.hookData.hook).onFillIntent(intent, state, _inputAmount+fee, _outputAmount);
IERC20(intent.inputToken).safeTransferFrom(data.hookData.hook, address(this), _inputAmount+fee);
}
resolveFill(intentHash, state, _inputAmount, _outputAmount, intent.inputToken, msg.sender, data.feeData);
}
function _externalFill(
Intent calldata intent,
bytes32 intentHash,
uint256 _inputAmount,
uint256 _outputAmount,
uint256 _externalFillId,
IntentData memory data
) internal {
if (!whitelistedSolvers[msg.sender]) revert Unauthorized();
if (data.hookData.hook != address(0)) revert ExternalFillNotAllowed();
bytes memory filler = spokes[intent.dstChain];
if (filler.length == 0) revert SpokeNotConfigured();
if (externalFills[_externalFillId].outputAmount != 0) revert FillAlreadyExists();
(uint256 chainID, bytes memory spokeAddress) = assetManager.assetInfo(intent.outputToken);
if (chainID != intent.dstChain) revert InvalidOutputToken();
PendingIntentState storage pendingState = pendingIntentStates[intentHash];
pendingState.pendingInput += _inputAmount;
pendingState.pendingOutput += _outputAmount;
pendingIntentStates[intentHash] = pendingState;
partnerFee[intentHash] = data.feeData;
Fill memory fill = Fill({
fillID: _externalFillId,
intentHash: abi.encode(intentHash),
solver: msg.sender.toBytes(),
receiver: intent.dstAddress,
token: spokeAddress,
amount: _outputAmount
});
externalFills[_externalFillId] = ExternalFill({
intentHash: intentHash,
to: msg.sender,
token: intent.inputToken,
inputAmount: _inputAmount,
outputAmount: _outputAmount
});
connection.sendMessage(intent.dstChain, filler, fill.encode());
}
/// @notice Receives and processes a verified cross-chain message.
/// @param srcChainId The chain ID of the originating chain.
/// @param srcAddress The address of the sender on the originating chain.
/// @param connSn The unique identifier for the message.
/// @param payload The encoded payload containing call data.
/// @param signatures An array of signatures for verifying the message.
function recvMessage(
uint256 srcChainId,
bytes calldata srcAddress,
uint256 connSn,
bytes memory payload,
bytes[] calldata signatures
) external nonReentrant {
connection.verifyMessage(srcChainId, srcAddress, connSn, payload, signatures);
require(keccak256(srcAddress) == keccak256(spokes[srcChainId]));
FillResponse memory fillResponse = FillLib.decodeResponse(payload);
ExternalFill memory externalFill = externalFills[fillResponse.fillID];
delete externalFills[fillResponse.fillID];
bytes32 intentHash = externalFill.intentHash;
PendingIntentState storage pendingState = pendingIntentStates[intentHash];
pendingState.pendingInput -= externalFill.inputAmount;
pendingState.pendingOutput -= externalFill.outputAmount;
if (pendingState.pendingInput == 0) {
delete pendingIntentStates[intentHash];
} else {
pendingIntentStates[intentHash] = pendingState;
}
if (!fillResponse.success) {
emit ExternalFillFailed(fillResponse.fillID, externalFill);
return;
}
IntentState storage state = intentStates[intentHash];
resolveFill(intentHash, state, externalFill.inputAmount, externalFill.outputAmount, externalFill.token, externalFill.to, partnerFee[intentHash]);
}
function resolveFill(bytes32 intentHash, IntentState storage state, uint256 _inputAmount, uint256 _outputAmount, address token, address solver, FeeData memory feeData) internal {
state.receivedOutput += _outputAmount;
state.remainingInput -= _inputAmount;
emit IntentFilled(intentHash, state);
uint256 fee = 0;
if (state.remainingInput == 0) {
fee = feeData.fee;
delete partnerFee[intentHash];
}
if (state.remainingInput == 0 && !state.pendingPayment) {
delete intentStates[intentHash];
} else {
intentStates[intentHash] = state;
}
if (state.pendingPayment) {
pendingPayouts[intentHash].push(Payout({
solver: solver,
amount: _inputAmount
}));
if (fee > 0) {
pendingPayouts[intentHash].push(Payout({
solver: feeData.receiver,
amount: fee
}));
}
} else {
transferToken(token, solver, _inputAmount);
if (fee > 0) {
transferToken(token, feeData.receiver, fee);
}
}
}
/// @notice Helper function to transfer tokens (native or ERC20)
/// @param token The token address to transfer (NATIVE_TOKEN for native token)
/// @param to The recipient address
/// @param amount The amount to transfer
function transferToken(address token, address to, uint256 amount) internal {
if (amount == 0) revert InvalidAmount();
if (token == NATIVE_TOKEN) {
(bool success, ) = to.call{value: amount}("");
if (!success) revert TransferFailed();
} else {
IERC20(token).safeTransfer(to, amount);
}
}
/// @notice Helper function to transfer tokens from sender (native or ERC20)
/// @param token The token address to transfer (NATIVE_TOKEN for native token)
/// @param amount The amount to transfer
function transferFrom(address token, uint256 amount) internal {
if (amount == 0) revert InvalidAmount();
if (token == NATIVE_TOKEN) {
if (msg.value != amount) revert InvalidAmount();
} else {
IERC20(token).safeTransferFrom(msg.sender, address(this), amount);
}
}
/// @notice Sends tokens to the appropriate destination based on chain configuration
/// @param token The token address to send
/// @param dstChainID The destination chain ID
/// @param to The recipient address
/// @param amount The amount to send
function sendToken(
address token,
uint256 dstChainID,
bytes memory to,
uint256 amount
) internal {
if (amount == 0) revert InvalidAmount();
if (dstChainID == HUB_CHAIN_ID) {
transferToken(token, AddressLib.toAddress(to), amount);
} else {
(uint256 chainID,) = assetManager.assetInfo(token);
if (dstChainID != chainID) revert("Invalid destination address or token");
assetManager.transfer(token, to, amount, '');
}
}
function processPendingPayouts(bytes32 intentHash, address token) internal {
Payout[] storage payouts = pendingPayouts[intentHash];
for (uint256 i = 0; i < payouts.length; i++) {
Payout memory payout = payouts[i];
transferToken(token, payout.solver, payout.amount);
}
delete pendingPayouts[intentHash];
}
// Add receive function to accept native token
receive() external payable {}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;
library console {
address constant CONSOLE_ADDRESS =
0x000000000000000000636F6e736F6c652e6c6f67;
function _sendLogPayloadImplementation(bytes memory payload) internal view {
address consoleAddress = CONSOLE_ADDRESS;
/// @solidity memory-safe-assembly
assembly {
pop(
staticcall(
gas(),
consoleAddress,
add(payload, 32),
mload(payload),
0,
0
)
)
}
}
function _castToPure(
function(bytes memory) internal view fnIn
) internal pure returns (function(bytes memory) pure fnOut) {
assembly {
fnOut := fnIn
}
}
function _sendLogPayload(bytes memory payload) internal pure {
_castToPure(_sendLogPayloadImplementation)(payload);
}
function log() internal pure {
_sendLogPayload(abi.encodeWithSignature("log()"));
}
function logInt(int256 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(int256)", p0));
}
function logUint(uint256 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256)", p0));
}
function logString(string memory p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string)", p0));
}
function logBool(bool p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool)", p0));
}
function logAddress(address p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address)", p0));
}
function logBytes(bytes memory p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes)", p0));
}
function logBytes1(bytes1 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes1)", p0));
}
function logBytes2(bytes2 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes2)", p0));
}
function logBytes3(bytes3 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes3)", p0));
}
function logBytes4(bytes4 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes4)", p0));
}
function logBytes5(bytes5 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes5)", p0));
}
function logBytes6(bytes6 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes6)", p0));
}
function logBytes7(bytes7 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes7)", p0));
}
function logBytes8(bytes8 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes8)", p0));
}
function logBytes9(bytes9 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes9)", p0));
}
function logBytes10(bytes10 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes10)", p0));
}
function logBytes11(bytes11 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes11)", p0));
}
function logBytes12(bytes12 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes12)", p0));
}
function logBytes13(bytes13 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes13)", p0));
}
function logBytes14(bytes14 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes14)", p0));
}
function logBytes15(bytes15 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes15)", p0));
}
function logBytes16(bytes16 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes16)", p0));
}
function logBytes17(bytes17 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes17)", p0));
}
function logBytes18(bytes18 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes18)", p0));
}
function logBytes19(bytes19 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes19)", p0));
}
function logBytes20(bytes20 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes20)", p0));
}
function logBytes21(bytes21 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes21)", p0));
}
function logBytes22(bytes22 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes22)", p0));
}
function logBytes23(bytes23 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes23)", p0));
}
function logBytes24(bytes24 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes24)", p0));
}
function logBytes25(bytes25 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes25)", p0));
}
function logBytes26(bytes26 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes26)", p0));
}
function logBytes27(bytes27 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes27)", p0));
}
function logBytes28(bytes28 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes28)", p0));
}
function logBytes29(bytes29 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes29)", p0));
}
function logBytes30(bytes30 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes30)", p0));
}
function logBytes31(bytes31 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes31)", p0));
}
function logBytes32(bytes32 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes32)", p0));
}
function log(uint256 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256)", p0));
}
function log(int256 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(int256)", p0));
}
function log(string memory p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string)", p0));
}
function log(bool p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool)", p0));
}
function log(address p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address)", p0));
}
function log(uint256 p0, uint256 p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256)", p0, p1));
}
function log(uint256 p0, string memory p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string)", p0, p1));
}
function log(uint256 p0, bool p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool)", p0, p1));
}
function log(uint256 p0, address p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address)", p0, p1));
}
function log(string memory p0, uint256 p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256)", p0, p1));
}
function log(string memory p0, int256 p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,int256)", p0, p1));
}
function log(string memory p0, string memory p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1));
}
function log(string memory p0, bool p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool)", p0, p1));
}
function log(string memory p0, address p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address)", p0, p1));
}
function log(bool p0, uint256 p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256)", p0, p1));
}
function log(bool p0, string memory p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string)", p0, p1));
}
function log(bool p0, bool p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool)", p0, p1));
}
function log(bool p0, address p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address)", p0, p1));
}
function log(address p0, uint256 p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256)", p0, p1));
}
function log(address p0, string memory p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string)", p0, p1));
}
function log(address p0, bool p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool)", p0, p1));
}
function log(address p0, address p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address)", p0, p1));
}
function log(uint256 p0, uint256 p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256)", p0, p1, p2));
}
function log(uint256 p0, uint256 p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string)", p0, p1, p2));
}
function log(uint256 p0, uint256 p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool)", p0, p1, p2));
}
function log(uint256 p0, uint256 p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address)", p0, p1, p2));
}
function log(uint256 p0, string memory p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256)", p0, p1, p2));
}
function log(uint256 p0, string memory p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,string)", p0, p1, p2));
}
function log(uint256 p0, string memory p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool)", p0, p1, p2));
}
function log(uint256 p0, string memory p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,address)", p0, p1, p2));
}
function log(uint256 p0, bool p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256)", p0, p1, p2));
}
function log(uint256 p0, bool p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string)", p0, p1, p2));
}
function log(uint256 p0, bool p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool)", p0, p1, p2));
}
function log(uint256 p0, bool p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address)", p0, p1, p2));
}
function log(uint256 p0, address p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256)", p0, p1, p2));
}
function log(uint256 p0, address p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,string)", p0, p1, p2));
}
function log(uint256 p0, address p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool)", p0, p1, p2));
}
function log(uint256 p0, address p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,address)", p0, p1, p2));
}
function log(string memory p0, uint256 p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256)", p0, p1, p2));
}
function log(string memory p0, uint256 p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,string)", p0, p1, p2));
}
function log(string memory p0, uint256 p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool)", p0, p1, p2));
}
function log(string memory p0, uint256 p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,address)", p0, p1, p2));
}
function log(string memory p0, string memory p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,uint256)", p0, p1, p2));
}
function log(string memory p0, string memory p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2));
}
function log(string memory p0, string memory p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2));
}
function log(string memory p0, string memory p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2));
}
function log(string memory p0, bool p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256)", p0, p1, p2));
}
function log(string memory p0, bool p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2));
}
function log(string memory p0, bool p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2));
}
function log(string memory p0, bool p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2));
}
function log(string memory p0, address p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,uint256)", p0, p1, p2));
}
function log(string memory p0, address p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2));
}
function log(string memory p0, address p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2));
}
function log(string memory p0, address p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2));
}
function log(bool p0, uint256 p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256)", p0, p1, p2));
}
function log(bool p0, uint256 p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string)", p0, p1, p2));
}
function log(bool p0, uint256 p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool)", p0, p1, p2));
}
function log(bool p0, uint256 p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address)", p0, p1, p2));
}
function log(bool p0, string memory p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256)", p0, p1, p2));
}
function log(bool p0, string memory p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2));
}
function log(bool p0, string memory p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2));
}
function log(bool p0, string memory p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2));
}
function log(bool p0, bool p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256)", p0, p1, p2));
}
function log(bool p0, bool p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2));
}
function log(bool p0, bool p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2));
}
function log(bool p0, bool p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2));
}
function log(bool p0, address p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256)", p0, p1, p2));
}
function log(bool p0, address p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2));
}
function log(bool p0, address p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2));
}
function log(bool p0, address p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2));
}
function log(address p0, uint256 p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256)", p0, p1, p2));
}
function log(address p0, uint256 p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,string)", p0, p1, p2));
}
function log(address p0, uint256 p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool)", p0, p1, p2));
}
function log(address p0, uint256 p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,address)", p0, p1, p2));
}
function log(address p0, string memory p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,uint256)", p0, p1, p2));
}
function log(address p0, string memory p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2));
}
function log(address p0, string memory p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2));
}
function log(address p0, string memory p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2));
}
function log(address p0, bool p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256)", p0, p1, p2));
}
function log(address p0, bool p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2));
}
function log(address p0, bool p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2));
}
function log(address p0, bool p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2));
}
function log(address p0, address p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,uint256)", p0, p1, p2));
}
function log(address p0, address p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2));
}
function log(address p0, address p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2));
}
function log(address p0, address p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2));
}
function log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,string)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,address)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,string)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,address)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,string)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,address)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,string)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,address)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,string)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,address)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,string)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,address)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,string)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,address)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,string)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,address)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,string)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,address)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,string)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,address)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,string)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,address)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,string)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,address)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,string)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,address)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,string)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,address)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,string)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,address)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,string)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,address)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,string)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,bool)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,address)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,string)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,bool)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,address)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,string)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,bool)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,address)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,string)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,bool)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,address)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,string)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,bool)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,address)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,string,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,string,string)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,string,bool)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,bool,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,bool,string)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,bool,bool)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,address,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,address,string)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,address,bool)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,string)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,bool)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,address)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,string,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,string,string)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,string,bool)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,string)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,bool)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,address)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,string,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,string,string)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,string,bool)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,address,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,uint256)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,string)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,bool)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,address)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,uint256)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,string)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,bool)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,address)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,uint256)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,string)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,bool)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,address)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,uint256)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,string)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,bool)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,address)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,uint256)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,string)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,bool)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,address)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,string,uint256)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,string,string)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,string,bool)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,uint256)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,uint256)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,uint256)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,string)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,bool)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,address)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,uint256)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,uint256)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,uint256)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3));
}
function log(bool p0, address p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,uint256)", p0, p1, p2, p3));
}
function log(bool p0, address p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,string)", p0, p1, p2, p3));
}
function log(bool p0, address p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,bool)", p0, p1, p2, p3));
}
function log(bool p0, address p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,address)", p0, p1, p2, p3));
}
function log(bool p0, address p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,uint256)", p0, p1, p2, p3));
}
function log(bool p0, address p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3));
}
function log(bool p0, address p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3));
}
function log(bool p0, address p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3));
}
function log(bool p0, address p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,uint256)", p0, p1, p2, p3));
}
function log(bool p0, address p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3));
}
function log(bool p0, address p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3));
}
function log(bool p0, address p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3));
}
function log(bool p0, address p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,uint256)", p0, p1, p2, p3));
}
function log(bool p0, address p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3));
}
function log(bool p0, address p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3));
}
function log(bool p0, address p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,uint256)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,string)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,bool)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,address)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,uint256)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,string)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,bool)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,address)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,uint256)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,string)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,bool)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,address)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,uint256)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,string)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,bool)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,address)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,uint256)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,string)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,bool)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,address)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,string,uint256)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,string,string)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,string,bool)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,uint256)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,address,uint256)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3));
}
function log(address p0, bool p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,uint256)", p0, p1, p2, p3));
}
function log(address p0, bool p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,string)", p0, p1, p2, p3));
}
function log(address p0, bool p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,bool)", p0, p1, p2, p3));
}
function log(address p0, bool p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,address)", p0, p1, p2, p3));
}
function log(address p0, bool p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,uint256)", p0, p1, p2, p3));
}
function log(address p0, bool p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3));
}
function log(address p0, bool p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3));
}
function log(address p0, bool p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3));
}
function log(address p0, bool p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,uint256)", p0, p1, p2, p3));
}
function log(address p0, bool p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3));
}
function log(address p0, bool p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3));
}
function log(address p0, bool p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3));
}
function log(address p0, bool p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,uint256)", p0, p1, p2, p3));
}
function log(address p0, bool p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3));
}
function log(address p0, bool p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3));
}
function log(address p0, bool p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3));
}
function log(address p0, address p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,uint256)", p0, p1, p2, p3));
}
function log(address p0, address p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,string)", p0, p1, p2, p3));
}
function log(address p0, address p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,bool)", p0, p1, p2, p3));
}
function log(address p0, address p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,address)", p0, p1, p2, p3));
}
function log(address p0, address p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,string,uint256)", p0, p1, p2, p3));
}
function log(address p0, address p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3));
}
function log(address p0, address p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3));
}
function log(address p0, address p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3));
}
function log(address p0, address p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,uint256)", p0, p1, p2, p3));
}
function log(address p0, address p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3));
}
function log(address p0, address p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3));
}
function log(address p0, address p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3));
}
function log(address p0, address p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,address,uint256)", p0, p1, p2, p3));
}
function log(address p0, address p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3));
}
function log(address p0, address p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3));
}
function log(address p0, address p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3));
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol)
pragma solidity ^0.8.20;
/**
* @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
* behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
* external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
* function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
*
* The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
* reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
* case an upgrade adds a module that needs to be initialized.
*
* For example:
*
* [.hljs-theme-light.nopadding]
* ```solidity
* contract MyToken is ERC20Upgradeable {
* function initialize() initializer public {
* __ERC20_init("MyToken", "MTK");
* }
* }
*
* contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
* function initializeV2() reinitializer(2) public {
* __ERC20Permit_init("MyToken");
* }
* }
* ```
*
* TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
* possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
*
* CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
* that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
*
* [CAUTION]
* ====
* Avoid leaving a contract uninitialized.
*
* An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
* contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
* the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
*
* [.hljs-theme-light.nopadding]
* ```
* /// @custom:oz-upgrades-unsafe-allow constructor
* constructor() {
* _disableInitializers();
* }
* ```
* ====
*/
abstract contract Initializable {
/**
* @dev Storage of the initializable contract.
*
* It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions
* when using with upgradeable contracts.
*
* @custom:storage-location erc7201:openzeppelin.storage.Initializable
*/
struct InitializableStorage {
/**
* @dev Indicates that the contract has been initialized.
*/
uint64 _initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool _initializing;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;
/**
* @dev The contract is already initialized.
*/
error InvalidInitialization();
/**
* @dev The contract is not initializing.
*/
error NotInitializing();
/**
* @dev Triggered when the contract has been initialized or reinitialized.
*/
event Initialized(uint64 version);
/**
* @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
* `onlyInitializing` functions can be used to initialize parent contracts.
*
* Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any
* number of times. This behavior in the constructor can be useful during testing and is not expected to be used in
* production.
*
* Emits an {Initialized} event.
*/
modifier initializer() {
// solhint-disable-next-line var-name-mixedcase
InitializableStorage storage $ = _getInitializableStorage();
// Cache values to avoid duplicated sloads
bool isTopLevelCall = !$._initializing;
uint64 initialized = $._initialized;
// Allowed calls:
// - initialSetup: the contract is not in the initializing state and no previous version was
// initialized
// - construction: the contract is initialized at version 1 (no reininitialization) and the
// current contract is just being deployed
bool initialSetup = initialized == 0 && isTopLevelCall;
bool construction = initialized == 1 && address(this).code.length == 0;
if (!initialSetup && !construction) {
revert InvalidInitialization();
}
$._initialized = 1;
if (isTopLevelCall) {
$._initializing = true;
}
_;
if (isTopLevelCall) {
$._initializing = false;
emit Initialized(1);
}
}
/**
* @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
* contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
* used to initialize parent contracts.
*
* A reinitializer may be used after the original initialization step. This is essential to configure modules that
* are added through upgrades and that require initialization.
*
* When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
* cannot be nested. If one is invoked in the context of another, execution will revert.
*
* Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
* a contract, executing them in the right order is up to the developer or operator.
*
* WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization.
*
* Emits an {Initialized} event.
*/
modifier reinitializer(uint64 version) {
// solhint-disable-next-line var-name-mixedcase
InitializableStorage storage $ = _getInitializableStorage();
if ($._initializing || $._initialized >= version) {
revert InvalidInitialization();
}
$._initialized = version;
$._initializing = true;
_;
$._initializing = false;
emit Initialized(version);
}
/**
* @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
* {initializer} and {reinitializer} modifiers, directly or indirectly.
*/
modifier onlyInitializing() {
_checkInitializing();
_;
}
/**
* @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.
*/
function _checkInitializing() internal view virtual {
if (!_isInitializing()) {
revert NotInitializing();
}
}
/**
* @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
* Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
* to any version. It is recommended to use this to lock implementation contracts that are designed to be called
* through proxies.
*
* Emits an {Initialized} event the first time it is successfully executed.
*/
function _disableInitializers() internal virtual {
// solhint-disable-next-line var-name-mixedcase
InitializableStorage storage $ = _getInitializableStorage();
if ($._initializing) {
revert InvalidInitialization();
}
if ($._initialized != type(uint64).max) {
$._initialized = type(uint64).max;
emit Initialized(type(uint64).max);
}
}
/**
* @dev Returns the highest version that has been initialized. See {reinitializer}.
*/
function _getInitializedVersion() internal view returns (uint64) {
return _getInitializableStorage()._initialized;
}
/**
* @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
*/
function _isInitializing() internal view returns (bool) {
return _getInitializableStorage()._initializing;
}
/**
* @dev Returns a pointer to the storage namespace.
*/
// solhint-disable-next-line var-name-mixedcase
function _getInitializableStorage() private pure returns (InitializableStorage storage $) {
assembly {
$.slot := INITIALIZABLE_STORAGE
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (access/Ownable2Step.sol)
pragma solidity ^0.8.20;
import {OwnableUpgradeable} from "./OwnableUpgradeable.sol";
import {Initializable} from "../proxy/utils/Initializable.sol";
/**
* @dev Contract module which provides access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* This extension of the {Ownable} contract includes a two-step mechanism to transfer
* ownership, where the new owner must call {acceptOwnership} in order to replace the
* old one. This can help prevent common mistakes, such as transfers of ownership to
* incorrect accounts, or to contracts that are unable to interact with the
* permission system.
*
* The initial owner is specified at deployment time in the constructor for `Ownable`. This
* can later be changed with {transferOwnership} and {acceptOwnership}.
*
* This module is used through inheritance. It will make available all functions
* from parent (Ownable).
*/
abstract contract Ownable2StepUpgradeable is Initializable, OwnableUpgradeable {
/// @custom:storage-location erc7201:openzeppelin.storage.Ownable2Step
struct Ownable2StepStorage {
address _pendingOwner;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Ownable2Step")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant Ownable2StepStorageLocation = 0x237e158222e3e6968b72b9db0d8043aacf074ad9f650f0d1606b4d82ee432c00;
function _getOwnable2StepStorage() private pure returns (Ownable2StepStorage storage $) {
assembly {
$.slot := Ownable2StepStorageLocation
}
}
event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);
function __Ownable2Step_init() internal onlyInitializing {
}
function __Ownable2Step_init_unchained() internal onlyInitializing {
}
/**
* @dev Returns the address of the pending owner.
*/
function pendingOwner() public view virtual returns (address) {
Ownable2StepStorage storage $ = _getOwnable2StepStorage();
return $._pendingOwner;
}
/**
* @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.
* Can only be called by the current owner.
*
* Setting `newOwner` to the zero address is allowed; this can be used to cancel an initiated ownership transfer.
*/
function transferOwnership(address newOwner) public virtual override onlyOwner {
Ownable2StepStorage storage $ = _getOwnable2StepStorage();
$._pendingOwner = newOwner;
emit OwnershipTransferStarted(owner(), newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual override {
Ownable2StepStorage storage $ = _getOwnable2StepStorage();
delete $._pendingOwner;
super._transferOwnership(newOwner);
}
/**
* @dev The new owner accepts the ownership transfer.
*/
function acceptOwnership() public virtual {
address sender = _msgSender();
if (pendingOwner() != sender) {
revert OwnableUnauthorizedAccount(sender);
}
_transferOwnership(sender);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (proxy/utils/UUPSUpgradeable.sol)
pragma solidity ^0.8.20;
import {IERC1822Proxiable} from "@openzeppelin/contracts/interfaces/draft-IERC1822.sol";
import {ERC1967Utils} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Utils.sol";
import {Initializable} from "./Initializable.sol";
/**
* @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an
* {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.
*
* A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is
* reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing
* `UUPSUpgradeable` with a custom implementation of upgrades.
*
* The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.
*/
abstract contract UUPSUpgradeable is Initializable, IERC1822Proxiable {
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable
address private immutable __self = address(this);
/**
* @dev The version of the upgrade interface of the contract. If this getter is missing, both `upgradeTo(address)`
* and `upgradeToAndCall(address,bytes)` are present, and `upgradeTo` must be used if no function should be called,
* while `upgradeToAndCall` will invoke the `receive` function if the second argument is the empty byte string.
* If the getter returns `"5.0.0"`, only `upgradeToAndCall(address,bytes)` is present, and the second argument must
* be the empty byte string if no function should be called, making it impossible to invoke the `receive` function
* during an upgrade.
*/
string public constant UPGRADE_INTERFACE_VERSION = "5.0.0";
/**
* @dev The call is from an unauthorized context.
*/
error UUPSUnauthorizedCallContext();
/**
* @dev The storage `slot` is unsupported as a UUID.
*/
error UUPSUnsupportedProxiableUUID(bytes32 slot);
/**
* @dev Check that the execution is being performed through a delegatecall call and that the execution context is
* a proxy contract with an implementation (as defined in ERC-1967) pointing to self. This should only be the case
* for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a
* function through ERC-1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to
* fail.
*/
modifier onlyProxy() {
_checkProxy();
_;
}
/**
* @dev Check that the execution is not being performed through a delegate call. This allows a function to be
* callable on the implementing contract but not through proxies.
*/
modifier notDelegated() {
_checkNotDelegated();
_;
}
function __UUPSUpgradeable_init() internal onlyInitializing {
}
function __UUPSUpgradeable_init_unchained() internal onlyInitializing {
}
/**
* @dev Implementation of the ERC-1822 {proxiableUUID} function. This returns the storage slot used by the
* implementation. It is used to validate the implementation's compatibility when performing an upgrade.
*
* IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks
* bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this
* function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.
*/
function proxiableUUID() external view virtual notDelegated returns (bytes32) {
return ERC1967Utils.IMPLEMENTATION_SLOT;
}
/**
* @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call
* encoded in `data`.
*
* Calls {_authorizeUpgrade}.
*
* Emits an {Upgraded} event.
*
* @custom:oz-upgrades-unsafe-allow-reachable delegatecall
*/
function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy {
_authorizeUpgrade(newImplementation);
_upgradeToAndCallUUPS(newImplementation, data);
}
/**
* @dev Reverts if the execution is not performed via delegatecall or the execution
* context is not of a proxy with an ERC-1967 compliant implementation pointing to self.
* See {_onlyProxy}.
*/
function _checkProxy() internal view virtual {
if (
address(this) == __self || // Must be called through delegatecall
ERC1967Utils.getImplementation() != __self // Must be called through an active proxy
) {
revert UUPSUnauthorizedCallContext();
}
}
/**
* @dev Reverts if the execution is performed via delegatecall.
* See {notDelegated}.
*/
function _checkNotDelegated() internal view virtual {
if (address(this) != __self) {
// Must not be called through delegatecall
revert UUPSUnauthorizedCallContext();
}
}
/**
* @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by
* {upgradeToAndCall}.
*
* Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.
*
* ```solidity
* function _authorizeUpgrade(address) internal onlyOwner {}
* ```
*/
function _authorizeUpgrade(address newImplementation) internal virtual;
/**
* @dev Performs an implementation upgrade with a security check for UUPS proxies, and additional setup call.
*
* As a security check, {proxiableUUID} is invoked in the new implementation, and the return value
* is expected to be the implementation slot in ERC-1967.
*
* Emits an {IERC1967-Upgraded} event.
*/
function _upgradeToAndCallUUPS(address newImplementation, bytes memory data) private {
try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {
if (slot != ERC1967Utils.IMPLEMENTATION_SLOT) {
revert UUPSUnsupportedProxiableUUID(slot);
}
ERC1967Utils.upgradeToAndCall(newImplementation, data);
} catch {
// The implementation is not UUPS
revert ERC1967Utils.ERC1967InvalidImplementation(newImplementation);
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/ReentrancyGuard.sol)
pragma solidity ^0.8.20;
import {Initializable} from "../proxy/utils/Initializable.sol";
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If EIP-1153 (transient storage) is available on the chain you're deploying at,
* consider using {ReentrancyGuardTransient} instead.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuardUpgradeable is Initializable {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant NOT_ENTERED = 1;
uint256 private constant ENTERED = 2;
/// @custom:storage-location erc7201:openzeppelin.storage.ReentrancyGuard
struct ReentrancyGuardStorage {
uint256 _status;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.ReentrancyGuard")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant ReentrancyGuardStorageLocation = 0x9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00;
function _getReentrancyGuardStorage() private pure returns (ReentrancyGuardStorage storage $) {
assembly {
$.slot := ReentrancyGuardStorageLocation
}
}
/**
* @dev Unauthorized reentrant call.
*/
error ReentrancyGuardReentrantCall();
function __ReentrancyGuard_init() internal onlyInitializing {
__ReentrancyGuard_init_unchained();
}
function __ReentrancyGuard_init_unchained() internal onlyInitializing {
ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();
$._status = NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();
// On the first call to nonReentrant, _status will be NOT_ENTERED
if ($._status == ENTERED) {
revert ReentrancyGuardReentrantCall();
}
// Any calls to nonReentrant after this point will fail
$._status = ENTERED;
}
function _nonReentrantAfter() private {
ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
$._status = NOT_ENTERED;
}
/**
* @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
* `nonReentrant` function in the call stack.
*/
function _reentrancyGuardEntered() internal view returns (bool) {
ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();
return $._status == ENTERED;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC-20 standard as defined in the ERC.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 value) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 value) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.20;
import {IERC20} from "../IERC20.sol";
import {IERC1363} from "../../../interfaces/IERC1363.sol";
import {Address} from "../../../utils/Address.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC-20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
/**
* @dev An operation with an ERC-20 token failed.
*/
error SafeERC20FailedOperation(address token);
/**
* @dev Indicates a failed `decreaseAllowance` request.
*/
error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);
/**
* @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));
}
/**
* @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
* calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
*/
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));
}
/**
* @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*
* IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client"
* smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using
* this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract
* that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.
*/
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
forceApprove(token, spender, oldAllowance + value);
}
/**
* @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no
* value, non-reverting calls are assumed to be successful.
*
* IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client"
* smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using
* this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract
* that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.
*/
function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {
unchecked {
uint256 currentAllowance = token.allowance(address(this), spender);
if (currentAllowance < requestedDecrease) {
revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);
}
forceApprove(token, spender, currentAllowance - requestedDecrease);
}
}
/**
* @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
* to be set to zero before setting it to a non-zero value, such as USDT.
*
* NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function
* only sets the "standard" allowance. Any temporary allowance will remain active, in addition to the value being
* set here.
*/
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));
_callOptionalReturn(token, approvalCall);
}
}
/**
* @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no
* code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
* targeting contracts.
*
* Reverts if the returned value is other than `true`.
*/
function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {
if (to.code.length == 0) {
safeTransfer(token, to, value);
} else if (!token.transferAndCall(to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target
* has no code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
* targeting contracts.
*
* Reverts if the returned value is other than `true`.
*/
function transferFromAndCallRelaxed(
IERC1363 token,
address from,
address to,
uint256 value,
bytes memory data
) internal {
if (to.code.length == 0) {
safeTransferFrom(token, from, to, value);
} else if (!token.transferFromAndCall(from, to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no
* code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
* targeting contracts.
*
* NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}.
* Opposedly, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall}
* once without retrying, and relies on the returned value to be true.
*
* Reverts if the returned value is other than `true`.
*/
function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {
if (to.code.length == 0) {
forceApprove(token, to, value);
} else if (!token.approveAndCall(to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*
* This is a variant of {_callOptionalReturnBool} that reverts if call fails to meet the requirements.
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
uint256 returnSize;
uint256 returnValue;
assembly ("memory-safe") {
let success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)
// bubble errors
if iszero(success) {
let ptr := mload(0x40)
returndatacopy(ptr, 0, returndatasize())
revert(ptr, returndatasize())
}
returnSize := returndatasize()
returnValue := mload(0)
}
if (returnSize == 0 ? address(token).code.length == 0 : returnValue != 1) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*
* This is a variant of {_callOptionalReturn} that silently catches all reverts and returns a bool instead.
*/
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
bool success;
uint256 returnSize;
uint256 returnValue;
assembly ("memory-safe") {
success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)
returnSize := returndatasize()
returnValue := mload(0)
}
return success && (returnSize == 0 ? address(token).code.length > 0 : returnValue == 1);
}
}// SPDX-License-Identifier: Apache-2.0
pragma solidity >=0.8.0;
pragma abicoder v2;
import '@openzeppelin-upgradeable/proxy/utils/Initializable.sol';
import '@openzeppelin-upgradeable/access/Ownable2StepUpgradeable.sol';
import '@openzeppelin-upgradeable/proxy/utils/UUPSUpgradeable.sol';
import 'openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Proxy.sol';
import {IConnection} from '../connection/IConnection.sol';
import {IWalletFactory} from '../wallet/IWalletFactory.sol';
import {IWallet} from '../wallet/IWallet.sol';
import {IAssetToken, AssetToken} from './AssetToken.sol';
import {IAssetManager} from './IAssetManager.sol';
import {Transfer, TransferLib} from './TransferLib.sol';
import '@contracts/utils/AddressLib.sol';
import '@contracts/utils/FeeM.sol';
contract AssetManager is
Initializable,
Ownable2StepUpgradeable,
UUPSUpgradeable,
IAssetManager,
FeeM
{
using TransferLib for Transfer;
using TransferLib for bytes;
using AddressLib for bytes;
using AddressLib for address;
event HookFailed(address wallet, string reason);
IConnection public connection;
IWalletFactory public walletFactory;
address public assetImplementation;
mapping(uint256 => bytes) public spokeAssetManager;
mapping(uint256 => mapping(bytes => address)) public assets;
mapping(address => AssetInfo) public override assetInfo;
/// @dev UUPS requires this function to restrict upgrades to authorized accounts.
function _authorizeUpgrade(
address newImplementation
) internal override onlyOwner {}
function initialize(
IConnection _connection,
IWalletFactory _walletFactory,
address _assetImplementation
) public initializer {
__Ownable_init(msg.sender);
__UUPSUpgradeable_init();
connection = _connection;
walletFactory = _walletFactory;
assetImplementation = _assetImplementation;
}
function getImplementation() external view returns (address) {
return ERC1967Utils.getImplementation();
}
function deployAsset(uint256 chainID, bytes memory addr) external override {
require(
spokeAssetManager[chainID].length != 0,
'Chain is not configured'
);
require(assets[chainID][addr] == address(0), 'Asset already exists');
ERC1967Proxy proxy = new ERC1967Proxy(
assetImplementation,
abi.encodeWithSelector(AssetToken.initialize.selector, '', '')
);
assets[chainID][addr] = address(proxy);
assetInfo[address(proxy)] = AssetInfo(chainID, addr);
}
function configureAssetManager(
uint256 chainID,
bytes memory addr
) external override onlyOwner {
spokeAssetManager[chainID] = addr;
}
function setAssetImpl(
address impl
) external onlyOwner {
assetImplementation = impl;
}
function upgradeToken(
uint256 chainID,
bytes memory addr,
address impl
) external override onlyOwner {
UUPSUpgradeable(assets[chainID][addr]).upgradeToAndCall(impl, '');
}
function overrideToken(
uint256 chainID,
bytes memory addr,
address asset
) external override onlyOwner {
address current = assets[chainID][addr];
delete assetInfo[current];
assets[chainID][addr] = asset;
assetInfo[asset] = AssetInfo(chainID, addr);
}
/// @notice Receives and processes a verified cross-chain message.
/// @param srcChainId The chain ID of the originating chain.
/// @param srcAddress The address of the sender on the originating chain.
/// @param connSn The unique identifier for the message.
/// @param payload The encoded payload containing call data.
/// @param signatures An array of signatures for verifying the message.
function recvMessage(
uint256 srcChainId,
bytes calldata srcAddress,
uint256 connSn,
bytes memory payload,
bytes[] calldata signatures
) external override {
connection.verifyMessage(
srcChainId,
srcAddress,
connSn,
payload,
signatures
);
_processMessage(srcChainId, srcAddress, payload, false);
}
/// @notice Simulates recvMessage without signature verification (view function)
/// @dev This function will always revert at the end to prevent actual state changes
/// @param srcChainId The chain ID of the originating chain
/// @param srcAddress The address of the sender on the originating chain
/// @param payload The encoded payload containing call data
function simulateRecvMessage(
uint256 srcChainId,
bytes calldata srcAddress,
bytes memory payload
) external {
_processMessage(srcChainId, srcAddress, payload, true);
revert('Simulation completed');
}
function _processMessage(
uint256 srcChainId,
bytes calldata srcAddress,
bytes memory payload,
bool simulation
) internal {
// Verify the message using the connection contract
require(
keccak256(srcAddress) == keccak256(spokeAssetManager[srcChainId])
);
Transfer memory _transfer = payload.decode();
address token = assets[srcChainId][_transfer.token];
address toAddress = _transfer.to.toAddress();
IAssetToken(token).mintTo(toAddress, _transfer.amount);
if (_transfer.data.length == 0) {
return;
}
address wallet = walletFactory.getWallet(srcChainId, _transfer.from);
try IWallet(wallet).assetManagerHook(token, _transfer.from, toAddress, _transfer.amount, _transfer.data) {
return;
} catch Error(string memory reason) {
if (simulation) {
revert(reason);
}
emit HookFailed(wallet, reason);
} catch (bytes memory) {
string memory reason = "unknown reason";
if (simulation) {
revert(reason);
}
emit HookFailed(wallet, reason);
}
}
function transfer(
address token,
bytes calldata to,
uint256 amount,
bytes calldata data
) external payable override {
AssetInfo memory info = assetInfo[token];
IAssetToken(token).burnFrom(msg.sender, amount);
Transfer memory _transfer = Transfer(
info.spokeAddress,
msg.sender.toBytes(),
to,
amount,
data
);
bytes memory manager = spokeAssetManager[info.chainID];
connection.sendMessage{value: msg.value}(
info.chainID,
manager,
_transfer.encode()
);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import '@openzeppelin/proxy/beacon/IBeacon.sol';
import '@openzeppelin-upgradeable/access/Ownable2StepUpgradeable.sol';
import '@openzeppelin-upgradeable/proxy/utils/UUPSUpgradeable.sol';
import '@openzeppelin-upgradeable/proxy/utils/Initializable.sol';
import './MinimalWalletProxy.sol';
import './IWalletFactory.sol';
import {CREATE3} from 'solmate/utils/CREATE3.sol';
import {console} from 'forge-std/console.sol';
import '@contracts/utils/FeeM.sol';
contract WalletFactory is Initializable, Ownable2StepUpgradeable, UUPSUpgradeable, IBeacon, IWalletFactory, FeeM {
address public implementation;
/// @notice Initializes the contract, setting the initial implementation and owner
/// @param _initialWalletImplementation The address of the initial implementation contract
function initialize(address _initialWalletImplementation) public initializer {
__Ownable_init(msg.sender);
__UUPSUpgradeable_init();
implementation = _initialWalletImplementation;
}
/// @notice Required by UUPSUpgradeable to authorize upgrades
/// @param newImplementation Address of the new implementation contract
function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}
function getImplementation() external view returns (address) {
return ERC1967Utils.getImplementation();
}
/// @notice Updates the wallet implementation contract address
/// @param _newWalletImplementation The address of the new wallet implementation contract
function updateWalletImplementation(address _newWalletImplementation) external onlyOwner {
implementation = _newWalletImplementation;
}
/// @notice Derive the address of a contract deployed with CREATE3
/// @param chainId chainId of address
/// @param user Users address on specified chain
/// @return computedAddress The derived contract address
function getWallet(uint256 chainId, bytes calldata user) external override returns (address computedAddress) {
// hash salt with the deployer address to give each deployer its own namespace
bytes32 salt = keccak256(abi.encodePacked(address(this), chainId, user));
computedAddress = CREATE3.getDeployed(salt);
if (computedAddress.code.length <= 0) {
computedAddress = this.deploy(salt);
emit Deployed(chainId, user, computedAddress);
}
return computedAddress;
}
/// @notice Deploy a contract deterministically with CREATE3
/// @param salt Unique salt to differentiate deployments
/// @return deployedAddress Address of the deployed contract
function deploy(bytes32 salt) public override returns (address deployedAddress) {
require(msg.sender == address(this), 'Can only be called by self');
bytes memory bytecode = abi.encodePacked(
type(MinimalWalletProxy).creationCode,
abi.encode(address(this))
);
deployedAddress = CREATE3.deploy(salt, bytecode, 0);
}
/// @notice Derive the address of a contract deployed with CREATE3
/// @param chainId chainId of address
/// @param user Users address on specified chain
/// @return computedAddress The derived contract address
function getDeployedAddress(uint256 chainId, bytes calldata user) external view override returns (address computedAddress) {
bytes32 salt = keccak256(abi.encodePacked(address(this), chainId, user));
computedAddress = CREATE3.getDeployed(salt);
}
}// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; // Common errors shared between Intents and IntentFiller error Unauthorized(); error InvalidAmount(); error TransferFailed(); error FillAlreadyExists(); error InvalidSourceChain(); error InvalidSourceAddress(); // Intent-specific errors error IntentAlreadyExists(); error IntentNotFound(); error InvalidIntent(); error InvalidDeadline(); error PartialFillNotAllowed(); error InvalidSolver(); error PendingFillExists(); error SpokeNotConfigured(); error InvalidOutputToken(); error ExternalFillNotAllowed(); // IntentFiller-specific errors error InsufficientValue(); error NotFiller(); error InvalidAddress(); error InvalidChainId(); error FillNotFound();
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {RLPEncode} from "../utils/RLPEncode.sol";
import {RLPReader} from "../utils/RLPReader.sol";
struct Fill {
uint256 fillID; // Unique identifier for the fill.
bytes intentHash; // Identifier for the intent being filled.
bytes solver; // Solver address on hub chain.
bytes receiver; // Sender address on the destination network.
bytes token; // Token address
uint256 amount; // Amount that the solver is receiving
}
struct FillResponse {
uint256 fillID; // Unique identifier for the fill.
bool success; // 0 for failure, 1 for success
}
library FillLib {
using RLPEncode for bytes;
using RLPEncode for uint256;
using RLPEncode for bytes[];
using RLPEncode for bool;
using RLPReader for bytes;
using RLPReader for uint;
using RLPReader for RLPReader.RLPItem;
using RLPReader for bool;
/// @notice Encodes a Fill struct into RLP format.
/// @param fill The Fill struct to encode.
/// @return The RLP-encoded bytes.
function encode(
Fill memory fill
) internal pure returns (bytes memory) {
bytes[] memory data = new bytes[](6);
data[0] = fill.fillID.encodeUint();
data[1] = fill.intentHash.encodeBytes();
data[2] = fill.solver.encodeBytes();
data[3] = fill.receiver.encodeBytes();
data[4] = fill.token.encodeBytes();
data[5] = fill.amount.encodeUint();
return data.encodeList();
}
function encodeResponse(
FillResponse memory fillResponse
) internal pure returns (bytes memory) {
bytes[] memory data = new bytes[](2);
data[0] = fillResponse.fillID.encodeUint();
data[1] = fillResponse.success.encodeBool();
return data.encodeList();
}
function decodeResponse(
bytes memory encoded
) internal pure returns (FillResponse memory) {
RLPReader.RLPItem[] memory data = encoded.toRlpItem().toList();
return FillResponse(
data[0].toUint(),
data[1].toBoolean()
);
}
/// @notice Decodes RLP-encoded bytes into a Fill struct.
/// @param encoded The RLP-encoded bytes.
/// @return The decoded Fill struct.
function decode(
bytes memory encoded
) internal pure returns (Fill memory) {
RLPReader.RLPItem[] memory data = encoded.toRlpItem().toList();
return Fill(
data[0].toUint(),
data[1].toBytes(),
data[2].toBytes(),
data[3].toBytes(),
data[4].toBytes(),
data[5].toUint()
);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {Intents} from './Intents.sol';
uint8 constant TYPE_ARRAY = 0;
uint8 constant TYPE_FEE = 1;
uint8 constant TYPE_HOOK = 2;
struct DataEntry {
uint8 dataType;
bytes data;
}
struct ArrayData {
DataEntry[] data;
}
struct IntentData {
FeeData feeData;
HookData hookData;
}
struct FeeData {
uint256 fee;
address receiver;
}
struct HookData {
address hook;
bytes data;
}
library IntentDataLib {
function calculateFee(Intents.Intent calldata intent, Intents.IntentState memory state, uint256 _inputAmount) internal pure returns (uint256) {
FeeData memory feeData = getData(intent).feeData;
if (feeData.fee == 0 || feeData.receiver == address(0)) return 0;
uint256 totalInput = intent.inputAmount;
uint256 filledBefore = totalInput - state.remainingInput;
uint256 filledAfter = filledBefore + _inputAmount;
uint256 expectedBefore = (feeData.fee * filledBefore) / totalInput;
uint256 expectedAfter = (feeData.fee * filledAfter) / totalInput;
return expectedAfter - expectedBefore;
}
// Unified decoding helpers
function getData(Intents.Intent calldata intent) internal pure returns (IntentData memory) {
if (intent.data.length == 0) return IntentData({feeData: FeeData({fee: 0, receiver: address(0)}), hookData: HookData({hook: address(0), data: bytes('')})});
return getData(intent.data);
}
function getData(bytes calldata rawData) internal pure returns (IntentData memory) {
if (rawData.length == 0) return IntentData({feeData: FeeData({fee: 0, receiver: address(0)}), hookData: HookData({hook: address(0), data: bytes('')})});
DataEntry memory topLevel = decodeIntentData(rawData);
if (topLevel.dataType == TYPE_FEE) {
return IntentData({feeData: decodeFeeData(topLevel.data), hookData: HookData({hook: address(0), data: bytes('')})});
}
if (topLevel.dataType == TYPE_HOOK) {
return IntentData({feeData: FeeData({fee: 0, receiver: address(0)}), hookData: decodeHookData(topLevel.data)});
}
if (topLevel.dataType == TYPE_ARRAY) {
ArrayData memory arrayData = decodeArrayData(topLevel.data);
return decodeArrayToData(arrayData);
}
return IntentData({feeData: FeeData({fee: 0, receiver: address(0)}), hookData: HookData({hook: address(0), data: bytes('')})});
}
function decodeArrayToData(ArrayData memory arrayData) internal pure returns (IntentData memory) {
FeeData memory fee = FeeData({fee: 0, receiver: address(0)});
HookData memory hook = HookData({hook: address(0), data: bytes('')});
for (uint256 i = 0; i < arrayData.data.length; i++) {
DataEntry memory item = arrayData.data[i];
if (item.dataType == TYPE_FEE && fee.receiver == address(0) && fee.fee == 0) {
fee = decodeFeeData(item.data);
} else if (item.dataType == TYPE_HOOK && hook.hook == address(0)) {
hook = decodeHookData(item.data);
}
}
return IntentData({feeData: fee, hookData: hook});
}
function decodeIntentData(bytes calldata rawData) internal pure returns (DataEntry memory) {
require(rawData.length >= 1, 'Invalid data length');
DataEntry memory intentData;
intentData.dataType = uint8(rawData[0]);
intentData.data = rawData[1:];
return intentData;
}
function decodeFeeData(bytes memory data) internal pure returns (FeeData memory) {
return abi.decode(data, (FeeData));
}
function decodeHookData(bytes memory data) internal pure returns (HookData memory) {
return abi.decode(data, (HookData));
}
function decodeArrayData(bytes memory data) internal pure returns (ArrayData memory) {
return abi.decode(data, (ArrayData));
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {Intents} from "./Intents.sol";
/// @title IIntentHooks
/// @notice Interface for intent hook callbacks that allow custom logic to be executed during the intent lifecycle
/// @dev All functions MUST only be callable by the `Intents` contract implementing the lifecycle.
interface IIntentHooks {
/// @notice Called during intent creation to validate compatibility and/or set up preconditions
/// @dev Revert to reject the creation. Do not perform external transfers here.
/// @param intent The intent being created
function onCreateIntent(Intents.Intent calldata intent) external;
/// @notice Determines whether an intent can be cancelled without the creator's permission
/// @dev Used when the caller is not the creator and the deadline has not yet passed.
/// @param intent The original intent
/// @param state The current on-chain state tracked by the `Intents` contract
/// @param remainingInput The amount of input remaining to be filled with fee
/// @return canCancel True if the hook permits cancellation, false otherwise
function isCancellable(Intents.Intent calldata intent, Intents.IntentState calldata state, uint256 remainingInput) external view returns (bool canCancel);
/// @notice Called when an intent is being cancelled to unwind any hook-specific state
/// @dev Use this to release approvals, repay temporary borrowings, or emit hook-specific events.
/// @param intent The original intent
/// @param repayAmount The amount of input (plus any fee portion) that will be returned to the creator
function onCancelIntent(Intents.Intent calldata intent, uint256 repayAmount) external;
/// @notice Called prior to executing a fill to perform any actions required by the hook (e.g., approvals)
/// @dev Should set any necessary allowance to the `Intents` contract or revert if preconditions are not met.
/// @param intent The original intent being filled
/// @param state The current on-chain state of the intent
/// @param inputAmount The amount of input tokens to be consumed by this fill
/// @param outputAmount The amount of output tokens to be delivered for this fill
function onFillIntent(
Intents.Intent calldata intent,
Intents.IntentState calldata state,
uint256 inputAmount,
uint256 outputAmount
) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract FeeM {
function registerMe() external {
(bool _success,) = address(0xDC2B0D2Dd2b7759D97D50db4eabDC36973110830).call(
abi.encodeWithSignature("selfRegister(uint256)", 158)
);
require(_success, "FeeM registration failed");
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
import {ContextUpgradeable} from "../utils/ContextUpgradeable.sol";
import {Initializable} from "../proxy/utils/Initializable.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* The initial owner is set to the address provided by the deployer. This can
* later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {
/// @custom:storage-location erc7201:openzeppelin.storage.Ownable
struct OwnableStorage {
address _owner;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Ownable")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant OwnableStorageLocation = 0x9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300;
function _getOwnableStorage() private pure returns (OwnableStorage storage $) {
assembly {
$.slot := OwnableStorageLocation
}
}
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
function __Ownable_init(address initialOwner) internal onlyInitializing {
__Ownable_init_unchained(initialOwner);
}
function __Ownable_init_unchained(address initialOwner) internal onlyInitializing {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
OwnableStorage storage $ = _getOwnableStorage();
return $._owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
OwnableStorage storage $ = _getOwnableStorage();
address oldOwner = $._owner;
$._owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (interfaces/draft-IERC1822.sol)
pragma solidity ^0.8.20;
/**
* @dev ERC-1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified
* proxy whose upgrades are fully controlled by the current implementation.
*/
interface IERC1822Proxiable {
/**
* @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation
* address.
*
* IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks
* bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this
* function revert if invoked through a proxy.
*/
function proxiableUUID() external view returns (bytes32);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (proxy/ERC1967/ERC1967Utils.sol)
pragma solidity ^0.8.21;
import {IBeacon} from "../beacon/IBeacon.sol";
import {IERC1967} from "../../interfaces/IERC1967.sol";
import {Address} from "../../utils/Address.sol";
import {StorageSlot} from "../../utils/StorageSlot.sol";
/**
* @dev This library provides getters and event emitting update functions for
* https://eips.ethereum.org/EIPS/eip-1967[ERC-1967] slots.
*/
library ERC1967Utils {
/**
* @dev Storage slot with the address of the current implementation.
* This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1.
*/
// solhint-disable-next-line private-vars-leading-underscore
bytes32 internal constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
/**
* @dev The `implementation` of the proxy is invalid.
*/
error ERC1967InvalidImplementation(address implementation);
/**
* @dev The `admin` of the proxy is invalid.
*/
error ERC1967InvalidAdmin(address admin);
/**
* @dev The `beacon` of the proxy is invalid.
*/
error ERC1967InvalidBeacon(address beacon);
/**
* @dev An upgrade function sees `msg.value > 0` that may be lost.
*/
error ERC1967NonPayable();
/**
* @dev Returns the current implementation address.
*/
function getImplementation() internal view returns (address) {
return StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value;
}
/**
* @dev Stores a new address in the ERC-1967 implementation slot.
*/
function _setImplementation(address newImplementation) private {
if (newImplementation.code.length == 0) {
revert ERC1967InvalidImplementation(newImplementation);
}
StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value = newImplementation;
}
/**
* @dev Performs implementation upgrade with additional setup call if data is nonempty.
* This function is payable only if the setup call is performed, otherwise `msg.value` is rejected
* to avoid stuck value in the contract.
*
* Emits an {IERC1967-Upgraded} event.
*/
function upgradeToAndCall(address newImplementation, bytes memory data) internal {
_setImplementation(newImplementation);
emit IERC1967.Upgraded(newImplementation);
if (data.length > 0) {
Address.functionDelegateCall(newImplementation, data);
} else {
_checkNonPayable();
}
}
/**
* @dev Storage slot with the admin of the contract.
* This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1.
*/
// solhint-disable-next-line private-vars-leading-underscore
bytes32 internal constant ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
/**
* @dev Returns the current admin.
*
* TIP: To get this value clients can read directly from the storage slot shown below (specified by ERC-1967) using
* the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.
* `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`
*/
function getAdmin() internal view returns (address) {
return StorageSlot.getAddressSlot(ADMIN_SLOT).value;
}
/**
* @dev Stores a new address in the ERC-1967 admin slot.
*/
function _setAdmin(address newAdmin) private {
if (newAdmin == address(0)) {
revert ERC1967InvalidAdmin(address(0));
}
StorageSlot.getAddressSlot(ADMIN_SLOT).value = newAdmin;
}
/**
* @dev Changes the admin of the proxy.
*
* Emits an {IERC1967-AdminChanged} event.
*/
function changeAdmin(address newAdmin) internal {
emit IERC1967.AdminChanged(getAdmin(), newAdmin);
_setAdmin(newAdmin);
}
/**
* @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.
* This is the keccak-256 hash of "eip1967.proxy.beacon" subtracted by 1.
*/
// solhint-disable-next-line private-vars-leading-underscore
bytes32 internal constant BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;
/**
* @dev Returns the current beacon.
*/
function getBeacon() internal view returns (address) {
return StorageSlot.getAddressSlot(BEACON_SLOT).value;
}
/**
* @dev Stores a new beacon in the ERC-1967 beacon slot.
*/
function _setBeacon(address newBeacon) private {
if (newBeacon.code.length == 0) {
revert ERC1967InvalidBeacon(newBeacon);
}
StorageSlot.getAddressSlot(BEACON_SLOT).value = newBeacon;
address beaconImplementation = IBeacon(newBeacon).implementation();
if (beaconImplementation.code.length == 0) {
revert ERC1967InvalidImplementation(beaconImplementation);
}
}
/**
* @dev Change the beacon and trigger a setup call if data is nonempty.
* This function is payable only if the setup call is performed, otherwise `msg.value` is rejected
* to avoid stuck value in the contract.
*
* Emits an {IERC1967-BeaconUpgraded} event.
*
* CAUTION: Invoking this function has no effect on an instance of {BeaconProxy} since v5, since
* it uses an immutable beacon without looking at the value of the ERC-1967 beacon slot for
* efficiency.
*/
function upgradeBeaconToAndCall(address newBeacon, bytes memory data) internal {
_setBeacon(newBeacon);
emit IERC1967.BeaconUpgraded(newBeacon);
if (data.length > 0) {
Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);
} else {
_checkNonPayable();
}
}
/**
* @dev Reverts if `msg.value` is not zero. It can be used to avoid `msg.value` stuck in the contract
* if an upgrade doesn't perform an initialization call.
*/
function _checkNonPayable() private {
if (msg.value > 0) {
revert ERC1967NonPayable();
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (interfaces/IERC1363.sol)
pragma solidity ^0.8.20;
import {IERC20} from "./IERC20.sol";
import {IERC165} from "./IERC165.sol";
/**
* @title IERC1363
* @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363].
*
* Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract
* after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction.
*/
interface IERC1363 is IERC20, IERC165 {
/*
* Note: the ERC-165 identifier for this interface is 0xb0202a11.
* 0xb0202a11 ===
* bytes4(keccak256('transferAndCall(address,uint256)')) ^
* bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^
* bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^
* bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^
* bytes4(keccak256('approveAndCall(address,uint256)')) ^
* bytes4(keccak256('approveAndCall(address,uint256,bytes)'))
*/
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferAndCall(address to, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @param data Additional data with no specified format, sent in call to `to`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param from The address which you want to send tokens from.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferFromAndCall(address from, address to, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param from The address which you want to send tokens from.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @param data Additional data with no specified format, sent in call to `to`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.
* @param spender The address which will spend the funds.
* @param value The amount of tokens to be spent.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function approveAndCall(address spender, uint256 value) external returns (bool);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.
* @param spender The address which will spend the funds.
* @param value The amount of tokens to be spent.
* @param data Additional data with no specified format, sent in call to `spender`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/Address.sol)
pragma solidity ^0.8.20;
import {Errors} from "./Errors.sol";
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev There's no code at `target` (it is not a contract).
*/
error AddressEmptyCode(address target);
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
if (address(this).balance < amount) {
revert Errors.InsufficientBalance(address(this).balance, amount);
}
(bool success, ) = recipient.call{value: amount}("");
if (!success) {
revert Errors.FailedCall();
}
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason or custom error, it is bubbled
* up by this function (like regular Solidity function calls). However, if
* the call reverted with no returned reason, this function reverts with a
* {Errors.FailedCall} error.
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
if (address(this).balance < value) {
revert Errors.InsufficientBalance(address(this).balance, value);
}
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target
* was not a contract or bubbling up the revert reason (falling back to {Errors.FailedCall}) in case
* of an unsuccessful call.
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata
) internal view returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
// only check if target is a contract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
if (returndata.length == 0 && target.code.length == 0) {
revert AddressEmptyCode(target);
}
return returndata;
}
}
/**
* @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the
* revert reason or with a default {Errors.FailedCall} error.
*/
function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
return returndata;
}
}
/**
* @dev Reverts with returndata if present. Otherwise reverts with {Errors.FailedCall}.
*/
function _revert(bytes memory returndata) private pure {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
assembly ("memory-safe") {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert Errors.FailedCall();
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (proxy/ERC1967/ERC1967Proxy.sol)
pragma solidity ^0.8.20;
import {Proxy} from "../Proxy.sol";
import {ERC1967Utils} from "./ERC1967Utils.sol";
/**
* @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an
* implementation address that can be changed. This address is stored in storage in the location specified by
* https://eips.ethereum.org/EIPS/eip-1967[ERC-1967], so that it doesn't conflict with the storage layout of the
* implementation behind the proxy.
*/
contract ERC1967Proxy is Proxy {
/**
* @dev Initializes the upgradeable proxy with an initial implementation specified by `implementation`.
*
* If `_data` is nonempty, it's used as data in a delegate call to `implementation`. This will typically be an
* encoded function call, and allows initializing the storage of the proxy like a Solidity constructor.
*
* Requirements:
*
* - If `data` is empty, `msg.value` must be zero.
*/
constructor(address implementation, bytes memory _data) payable {
ERC1967Utils.upgradeToAndCall(implementation, _data);
}
/**
* @dev Returns the current implementation address.
*
* TIP: To get this value clients can read directly from the storage slot shown below (specified by ERC-1967) using
* the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.
* `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`
*/
function _implementation() internal view virtual override returns (address) {
return ERC1967Utils.getImplementation();
}
}// SPDX-License-Identifier: Apache-2.0
pragma solidity >=0.8.0;
interface IConnection {
function sendMessage(
uint256 dstChainId,
bytes memory dstAddress,
bytes memory payload
) external payable;
function verifyMessage(
uint256 srcChainId,
bytes calldata srcAddress,
uint256 connSn,
bytes memory payload,
bytes[] calldata signatures
) external;
function chainId() external view returns (uint256);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IWalletFactory {
// Events
event Deployed(uint256 indexed chainId, bytes indexed spokeAddress, address deployedAddress);
// Function signatures
/// @notice Updates the wallet implementation contract address
/// @param _newWalletImplementation The address of the new wallet implementation contract
function updateWalletImplementation(address _newWalletImplementation) external;
/// @notice Derive the address of a contract deployed with CREATE3
/// @param chainId chainId of address
/// @param user User's address on the specified chain
/// @return computedAddress The derived contract address
function getWallet(uint256 chainId, bytes calldata user) external returns (address computedAddress);
/// @notice Deploy a contract deterministically with CREATE3
/// @param salt Unique salt to differentiate deployments
/// @return deployedAddress Address of the deployed contract
function deploy(bytes32 salt) external returns (address deployedAddress);
/// @notice Derive the address of a contract deployed with CREATE3
/// @param chainId chainId of address
/// @param user User's address on the specified chain
/// @return computedAddress The derived contract address
function getDeployedAddress(uint256 chainId, bytes calldata user) external view returns (address computedAddress);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/// @title IWallet Interface
/// @notice Interface for the Wallet contract.
interface IWallet {
/// @notice Represents a contract call to be executed.
struct ContractCall {
address addr; // Target address of the call
uint256 value; // Ether value to send
bytes data; // Calldata for the call
}
struct TransferData {
address token;
bytes from;
address to;
uint256 amount;
bytes data;
}
/// @notice Receives and processes a verified cross-chain message.
/// @param srcChainId The chain ID of the originating chain.
/// @param srcAddress The address of the sender on the originating chain.
/// @param _connSn The unique identifier for the message.
/// @param _payload The encoded payload containing call data.
/// @param signatures An array of signatures for verifying the message.
function recvMessage(
uint256 srcChainId,
bytes calldata srcAddress,
uint256 _connSn,
bytes memory _payload,
bytes[] calldata signatures
) external;
/// @notice Allows the asset manager to execute calls on behalf of the wallet.
/// @param token The address of the token being transferred.
/// @param from The address of the sender.
/// @param to The address of the recipient.
/// @param amount The amount of tokens being transferred.
/// @param data data associated with the transfer.
function assetManagerHook(address token, bytes memory from, address to, uint256 amount, bytes memory data) external;
/// @notice Reverts a stored call.
/// @param callHash The hash of the stored call.
function revertStored(bytes32 callHash) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import '@openzeppelin-upgradeable/proxy/utils/Initializable.sol';
import '@openzeppelin-upgradeable/token/ERC20/ERC20Upgradeable.sol';
import '@openzeppelin-upgradeable/proxy/utils/UUPSUpgradeable.sol';
import '@openzeppelin-upgradeable/access/OwnableUpgradeable.sol';
import '@contracts/utils/FeeM.sol';
interface IAssetToken {
// Mint tokens to a specific address
function mintTo(address to, uint256 amount) external;
// Burn tokens from a specific address
function burnFrom(address from, uint256 amount) external;
}
contract AssetToken is ERC20Upgradeable, UUPSUpgradeable, OwnableUpgradeable, IAssetToken, FeeM {
function initialize(string memory name, string memory symbol) public initializer {
__ERC20_init(name, symbol);
__Ownable_init(msg.sender);
}
// Authorization for UUPS upgradability
function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}
function getImplementation() external view returns (address) {
return ERC1967Utils.getImplementation();
}
// Mint tokens to a specific address
function mintTo(address to, uint256 amount) external override onlyOwner {
_mint(to, amount);
}
// Burn tokens from a specific address
function burnFrom(address from, uint256 amount) external override onlyOwner {
_burn(from, amount);
}
function decimals() public view override returns (uint8) {
return 0;
}
}// SPDX-License-Identifier: Apache-2.0
pragma solidity >=0.8.0;
interface IAssetManager {
struct AssetInfo {
uint256 chainID;
bytes spokeAddress;
}
function deployAsset(uint256 chainID, bytes memory addr) external;
function configureAssetManager(uint256 chainID, bytes memory addr) external;
function upgradeToken(uint256 chainID, bytes memory addr, address impl) external;
function overrideToken(uint256 chainID, bytes memory addr, address asset) external;
function assetInfo(address asset) external view returns (uint256 chainID, bytes memory spokeAddress);
function recvMessage(
uint256 srcChainId,
bytes calldata srcAddress,
uint256 connSn,
bytes memory payload,
bytes[] calldata signatures
) external;
function transfer(
address token,
bytes calldata to,
uint256 amount,
bytes calldata data
) external payable;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {RLPEncode} from '../utils/RLPEncode.sol';
import {RLPReader} from '../utils/RLPReader.sol';
struct Transfer {
bytes token; // Identifier for the asset being transferred.
bytes from; // Sender address on the originating network.
bytes to; // Recipient address on the destination network.
uint256 amount; // Amount of the asset to transfer.
bytes data; // Encoded data to facilitate additional logic.
}
library TransferLib {
using RLPEncode for bytes;
using RLPEncode for bytes[];
using RLPEncode for uint256;
using RLPReader for bytes;
using RLPReader for uint;
using RLPReader for RLPReader.RLPItem;
/// @notice Encodes a Transfer struct into RLP format.
/// @param transfer The Transfer struct to encode.
/// @return The RLP-encoded bytes.
function encode(
Transfer memory transfer
) internal pure returns (bytes memory) {
bytes[] memory data = new bytes[](5);
data[0] = transfer.token.encodeBytes();
data[1] = transfer.from.encodeBytes();
data[2] = transfer.to.encodeBytes();
data[3] = transfer.amount.encodeUint();
data[4] = transfer.data.encodeBytes();
return data.encodeList();
}
/// @notice Decodes RLP-encoded bytes into a Transfer struct.
/// @param encoded The RLP-encoded bytes.
/// @return The decoded Transfer struct.
function decode(
bytes memory encoded
) internal pure returns (Transfer memory) {
RLPReader.RLPItem[] memory data = encoded.toRlpItem().toList();
return Transfer(
data[0].toBytes(),
data[1].toBytes(),
data[2].toBytes(),
data[3].toUint(),
data[4].toBytes()
);
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0 ;
library AddressLib {
function toAddress(bytes memory addrBytes) internal pure returns (address) {
require(addrBytes.length == 20, "Invalid data length");
address decodedAddress;
// Inline assembly for efficient decoding
assembly {
decodedAddress := mload(add(addrBytes, 20))
}
return decodedAddress;
}
function toBytes(address _address) internal pure returns (bytes memory) {
return abi.encodePacked(_address);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (proxy/beacon/IBeacon.sol)
pragma solidity ^0.8.20;
/**
* @dev This is the interface that {BeaconProxy} expects of its beacon.
*/
interface IBeacon {
/**
* @dev Must return an address that can be used as a delegate call target.
*
* {UpgradeableBeacon} will check that this address is a contract.
*/
function implementation() external view returns (address);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import '@openzeppelin/proxy/beacon/IBeacon.sol';
contract MinimalWalletProxy {
address public immutable beacon;
constructor(address _beacon) {
beacon = _beacon;
}
fallback() external payable {
// Fetch implementation address from the beacon
address implementation = IBeacon(beacon).implementation();
assembly {
// Copy calldata to memory
calldatacopy(0, 0, calldatasize())
// Perform delegatecall to the implementation
let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)
// Copy returndata to memory
returndatacopy(0, 0, returndatasize())
// Check result and revert if delegatecall failed
switch result
case 0 { revert(0, returndatasize()) }
default { return(0, returndatasize()) }
}
}
// Optional: Receive function to handle plain Ether transfers
receive() external payable {}
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {Bytes32AddressLib} from "./Bytes32AddressLib.sol";
/// @notice Deploy to deterministic addresses without an initcode factor.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/CREATE3.sol)
/// @author Modified from 0xSequence (https://github.com/0xSequence/create3/blob/master/contracts/Create3.sol)
library CREATE3 {
using Bytes32AddressLib for bytes32;
//--------------------------------------------------------------------------------//
// Opcode | Opcode + Arguments | Description | Stack View //
//--------------------------------------------------------------------------------//
// 0x36 | 0x36 | CALLDATASIZE | size //
// 0x3d | 0x3d | RETURNDATASIZE | 0 size //
// 0x3d | 0x3d | RETURNDATASIZE | 0 0 size //
// 0x37 | 0x37 | CALLDATACOPY | //
// 0x36 | 0x36 | CALLDATASIZE | size //
// 0x3d | 0x3d | RETURNDATASIZE | 0 size //
// 0x34 | 0x34 | CALLVALUE | value 0 size //
// 0xf0 | 0xf0 | CREATE | newContract //
//--------------------------------------------------------------------------------//
// Opcode | Opcode + Arguments | Description | Stack View //
//--------------------------------------------------------------------------------//
// 0x67 | 0x67XXXXXXXXXXXXXXXX | PUSH8 bytecode | bytecode //
// 0x3d | 0x3d | RETURNDATASIZE | 0 bytecode //
// 0x52 | 0x52 | MSTORE | //
// 0x60 | 0x6008 | PUSH1 08 | 8 //
// 0x60 | 0x6018 | PUSH1 18 | 24 8 //
// 0xf3 | 0xf3 | RETURN | //
//--------------------------------------------------------------------------------//
bytes internal constant PROXY_BYTECODE = hex"67_36_3d_3d_37_36_3d_34_f0_3d_52_60_08_60_18_f3";
bytes32 internal constant PROXY_BYTECODE_HASH = keccak256(PROXY_BYTECODE);
function deploy(
bytes32 salt,
bytes memory creationCode,
uint256 value
) internal returns (address deployed) {
bytes memory proxyChildBytecode = PROXY_BYTECODE;
address proxy;
/// @solidity memory-safe-assembly
assembly {
// Deploy a new contract with our pre-made bytecode via CREATE2.
// We start 32 bytes into the code to avoid copying the byte length.
proxy := create2(0, add(proxyChildBytecode, 32), mload(proxyChildBytecode), salt)
}
require(proxy != address(0), "DEPLOYMENT_FAILED");
deployed = getDeployed(salt);
(bool success, ) = proxy.call{value: value}(creationCode);
require(success && deployed.code.length != 0, "INITIALIZATION_FAILED");
}
function getDeployed(bytes32 salt) internal view returns (address) {
return getDeployed(salt, address(this));
}
function getDeployed(bytes32 salt, address creator) internal pure returns (address) {
address proxy = keccak256(
abi.encodePacked(
// Prefix:
bytes1(0xFF),
// Creator:
creator,
// Salt:
salt,
// Bytecode hash:
PROXY_BYTECODE_HASH
)
).fromLast20Bytes();
return
keccak256(
abi.encodePacked(
// 0xd6 = 0xc0 (short RLP prefix) + 0x16 (length of: 0x94 ++ proxy ++ 0x01)
// 0x94 = 0x80 + 0x14 (0x14 = the length of an address, 20 bytes, in hex)
hex"d6_94",
proxy,
hex"01" // Nonce of the proxy contract (1)
)
).fromLast20Bytes();
}
}pragma solidity >=0.4.0 ;
/**
* @title RLPEncode
* @dev A simple RLP encoding library.
* @author Bakaoh
*/
library RLPEncode {
/*
* Internal functions
*/
/**
* @dev RLP encodes a byte string.
* @param self The byte string to encode.
* @return The RLP encoded string in bytes.
*/
function encodeBytes(bytes memory self) internal pure returns (bytes memory) {
bytes memory encoded;
if (self.length == 1 && uint8(self[0]) < 128) {
encoded = self;
} else {
encoded = concat(encodeLength(self.length, 128), self);
}
return encoded;
}
/**
* @dev RLP encodes a list of RLP encoded byte byte strings.
* @param self The list of RLP encoded byte strings.
* @return The RLP encoded list of items in bytes.
*/
function encodeList(bytes[] memory self) internal pure returns (bytes memory) {
bytes memory list = flatten(self);
return concat(encodeLength(list.length, 192), list);
}
/**
* @dev RLP encodes a string.
* @param self The string to encode.
* @return The RLP encoded string in bytes.
*/
function encodeString(string memory self) internal pure returns (bytes memory) {
return encodeBytes(bytes(self));
}
/**
* @dev RLP encodes an address.
* @param self The address to encode.
* @return The RLP encoded address in bytes.
*/
function encodeAddress(address self) internal pure returns (bytes memory) {
bytes memory inputBytes;
assembly {
let m := mload(0x40)
mstore(add(m, 20), xor(0x140000000000000000000000000000000000000000, self))
mstore(0x40, add(m, 52))
inputBytes := m
}
return encodeBytes(inputBytes);
}
/**
* @dev RLP encodes a uint.
* @param self The uint to encode.
* @return The RLP encoded uint in bytes.
*/
function encodeUint(uint self) internal pure returns (bytes memory) {
return encodeBytes(toBinary(self));
}
/**
* @dev RLP encodes an int.
* @param self The int to encode.
* @return The RLP encoded int in bytes.
*/
function encodeInt(int self) internal pure returns (bytes memory) {
return encodeUint(uint(self));
}
/**
* @dev RLP encodes a bool.
* @param self The bool to encode.
* @return The RLP encoded bool in bytes.
*/
function encodeBool(bool self) internal pure returns (bytes memory) {
bytes memory encoded = new bytes(1);
encoded[0] = (self ? bytes1(0x01) : bytes1(0x80));
return encoded;
}
/*
* Private functions
*/
/**
* @dev Encode the first byte, followed by the `len` in binary form if `length` is more than 55.
* @param len The length of the string or the payload.
* @param offset 128 if item is string, 192 if item is list.
* @return RLP encoded bytes.
*/
function encodeLength(uint len, uint offset) private pure returns (bytes memory) {
bytes memory encoded;
if (len < 56) {
encoded = new bytes(1);
encoded[0] = bytes32(len + offset)[31];
} else {
uint lenLen;
uint i = 1;
while (len / i != 0) {
lenLen++;
i *= 256;
}
encoded = new bytes(lenLen + 1);
encoded[0] = bytes32(lenLen + offset + 55)[31];
for(i = 1; i <= lenLen; i++) {
encoded[i] = bytes32((len / (256**(lenLen-i))) % 256)[31];
}
}
return encoded;
}
/**
* @dev Encode integer in big endian binary form with no leading zeroes.
* @notice TODO: This should be optimized with assembly to save gas costs.
* @param _x The integer to encode.
* @return RLP encoded bytes.
*/
function toBinary(uint _x) private pure returns (bytes memory) {
bytes memory b = new bytes(32);
assembly {
mstore(add(b, 32), _x)
}
uint i;
for (i = 0; i < 32; i++) {
if (b[i] != 0) {
break;
}
}
bytes memory res = new bytes(32 - i);
for (uint j = 0; j < res.length; j++) {
res[j] = b[i++];
}
return res;
}
/**
* @dev Copies a piece of memory to another location.
* @notice From: https://github.com/Arachnid/solidity-stringutils/blob/master/src/strings.sol.
* @param _dest Destination location.
* @param _src Source location.
* @param _len Length of memory to copy.
*/
function memcpy(uint _dest, uint _src, uint _len) private pure {
uint dest = _dest;
uint src = _src;
uint len = _len;
for(; len >= 32; len -= 32) {
assembly {
mstore(dest, mload(src))
}
dest += 32;
src += 32;
}
if (len > 0) {
uint mask = 256 ** (32 - len) - 1;
assembly {
let srcpart := and(mload(src), not(mask))
let destpart := and(mload(dest), mask)
mstore(dest, or(destpart, srcpart))
}
}
}
/**
* @dev Flattens a list of byte strings into one byte string.
* @notice From: https://github.com/sammayo/solidity-rlp-encoder/blob/master/RLPEncode.sol.
* @param _list List of byte strings to flatten.
* @return The flattened byte string.
*/
function flatten(bytes[] memory _list) private pure returns (bytes memory) {
if (_list.length == 0) {
return new bytes(0);
}
uint len;
uint i;
for (i = 0; i < _list.length; i++) {
require(_list[i].length > 0, "An item in the list to be RLP encoded is null.");
len += _list[i].length;
}
bytes memory flattened = new bytes(len);
uint flattenedPtr;
assembly { flattenedPtr := add(flattened, 0x20) }
for(i = 0; i < _list.length; i++) {
bytes memory item = _list[i];
uint listPtr;
assembly { listPtr := add(item, 0x20)}
memcpy(flattenedPtr, listPtr, item.length);
flattenedPtr += _list[i].length;
}
return flattened;
}
/**
* @dev Concatenates two bytes.
* @notice From: https://github.com/GNSPS/solidity-bytes-utils/blob/master/contracts/BytesLib.sol.
* @param _preBytes First byte string.
* @param _postBytes Second byte string.
* @return Both byte string combined.
*/
function concat(bytes memory _preBytes, bytes memory _postBytes) private pure returns (bytes memory) {
bytes memory tempBytes;
assembly {
tempBytes := mload(0x40)
let length := mload(_preBytes)
mstore(tempBytes, length)
let mc := add(tempBytes, 0x20)
let end := add(mc, length)
for {
let cc := add(_preBytes, 0x20)
} lt(mc, end) {
mc := add(mc, 0x20)
cc := add(cc, 0x20)
} {
mstore(mc, mload(cc))
}
length := mload(_postBytes)
mstore(tempBytes, add(length, mload(tempBytes)))
mc := end
end := add(mc, length)
for {
let cc := add(_postBytes, 0x20)
} lt(mc, end) {
mc := add(mc, 0x20)
cc := add(cc, 0x20)
} {
mstore(mc, mload(cc))
}
mstore(0x40, and(
add(add(end, iszero(add(length, mload(_preBytes)))), 31),
not(31)
))
}
return tempBytes;
}
}// SPDX-License-Identifier: Apache-2.0 /* * @author Hamdi Allam [email protected] * Please reach out with any questions or concerns */ pragma solidity >=0.5.10 <0.9.0; library RLPReader { uint8 constant STRING_SHORT_START = 0x80; uint8 constant STRING_LONG_START = 0xb8; uint8 constant LIST_SHORT_START = 0xc0; uint8 constant LIST_LONG_START = 0xf8; uint8 constant WORD_SIZE = 32; struct RLPItem { uint256 len; uint256 memPtr; } struct Iterator { RLPItem item; // Item that's being iterated over. uint256 nextPtr; // Position of the next item in the list. } /* * @dev Returns the next element in the iteration. Reverts if it has not next element. * @param self The iterator. * @return The next element in the iteration. */ function next(Iterator memory self) internal pure returns (RLPItem memory) { require(hasNext(self)); uint256 ptr = self.nextPtr; uint256 itemLength = _itemLength(ptr); self.nextPtr = ptr + itemLength; return RLPItem(itemLength, ptr); } /* * @dev Returns true if the iteration has more elements. * @param self The iterator. * @return true if the iteration has more elements. */ function hasNext(Iterator memory self) internal pure returns (bool) { RLPItem memory item = self.item; return self.nextPtr < item.memPtr + item.len; } /* * @param item RLP encoded bytes */ function toRlpItem(bytes memory item) internal pure returns (RLPItem memory) { uint256 memPtr; assembly { memPtr := add(item, 0x20) } return RLPItem(item.length, memPtr); } /* * @dev Create an iterator. Reverts if item is not a list. * @param self The RLP item. * @return An 'Iterator' over the item. */ function iterator(RLPItem memory self) internal pure returns (Iterator memory) { require(isList(self)); uint256 ptr = self.memPtr + _payloadOffset(self.memPtr); return Iterator(self, ptr); } /* * @param the RLP item. */ function rlpLen(RLPItem memory item) internal pure returns (uint256) { return item.len; } /* * @param the RLP item. * @return (memPtr, len) pair: location of the item's payload in memory. */ function payloadLocation(RLPItem memory item) internal pure returns (uint256, uint256) { uint256 offset = _payloadOffset(item.memPtr); uint256 memPtr = item.memPtr + offset; uint256 len = item.len - offset; // data length return (memPtr, len); } /* * @param the RLP item. */ function payloadLen(RLPItem memory item) internal pure returns (uint256) { (, uint256 len) = payloadLocation(item); return len; } /* * @param the RLP item containing the encoded list. */ function toList(RLPItem memory item) internal pure returns (RLPItem[] memory) { require(isList(item)); uint256 items = numItems(item); RLPItem[] memory result = new RLPItem[](items); uint256 memPtr = item.memPtr + _payloadOffset(item.memPtr); uint256 dataLen; for (uint256 i = 0; i < items; i++) { dataLen = _itemLength(memPtr); result[i] = RLPItem(dataLen, memPtr); memPtr = memPtr + dataLen; } return result; } // @return indicator whether encoded payload is a list. negate this function call for isData. function isList(RLPItem memory item) internal pure returns (bool) { if (item.len == 0) return false; uint8 byte0; uint256 memPtr = item.memPtr; assembly { byte0 := byte(0, mload(memPtr)) } if (byte0 < LIST_SHORT_START) return false; return true; } /* * @dev A cheaper version of keccak256(toRlpBytes(item)) that avoids copying memory. * @return keccak256 hash of RLP encoded bytes. */ function rlpBytesKeccak256(RLPItem memory item) internal pure returns (bytes32) { uint256 ptr = item.memPtr; uint256 len = item.len; bytes32 result; assembly { result := keccak256(ptr, len) } return result; } /* * @dev A cheaper version of keccak256(toBytes(item)) that avoids copying memory. * @return keccak256 hash of the item payload. */ function payloadKeccak256(RLPItem memory item) internal pure returns (bytes32) { (uint256 memPtr, uint256 len) = payloadLocation(item); bytes32 result; assembly { result := keccak256(memPtr, len) } return result; } /** RLPItem conversions into data types **/ // @returns raw rlp encoding in bytes function toRlpBytes(RLPItem memory item) internal pure returns (bytes memory) { bytes memory result = new bytes(item.len); if (result.length == 0) return result; uint256 ptr; assembly { ptr := add(0x20, result) } copy(item.memPtr, ptr, item.len); return result; } // any non-zero byte except "0x80" is considered true function toBoolean(RLPItem memory item) internal pure returns (bool) { require(item.len == 1); uint256 result; uint256 memPtr = item.memPtr; assembly { result := byte(0, mload(memPtr)) } // SEE Github Issue #5. // Summary: Most commonly used RLP libraries (i.e Geth) will encode // "0" as "0x80" instead of as "0". We handle this edge case explicitly // here. if (result == 0 || result == STRING_SHORT_START) { return false; } else { return true; } } function toAddress(RLPItem memory item) internal pure returns (address) { // 1 byte for the length prefix require(item.len == 21); return address(uint160(toUint(item))); } function toUint(RLPItem memory item) internal pure returns (uint256) { require(item.len > 0 && item.len <= 33); (uint256 memPtr, uint256 len) = payloadLocation(item); uint256 result; assembly { result := mload(memPtr) // shift to the correct location if neccesary if lt(len, 32) { result := div(result, exp(256, sub(32, len))) } } return result; } // enforces 32 byte length function toUintStrict(RLPItem memory item) internal pure returns (uint256) { // one byte prefix require(item.len == 33); uint256 result; uint256 memPtr = item.memPtr + 1; assembly { result := mload(memPtr) } return result; } function toBytes(RLPItem memory item) internal pure returns (bytes memory) { require(item.len > 0); (uint256 memPtr, uint256 len) = payloadLocation(item); bytes memory result = new bytes(len); uint256 destPtr; assembly { destPtr := add(0x20, result) } copy(memPtr, destPtr, len); return result; } /* * Private Helpers */ // @return number of payload items inside an encoded list. function numItems(RLPItem memory item) private pure returns (uint256) { if (item.len == 0) return 0; uint256 count = 0; uint256 currPtr = item.memPtr + _payloadOffset(item.memPtr); uint256 endPtr = item.memPtr + item.len; while (currPtr < endPtr) { currPtr = currPtr + _itemLength(currPtr); // skip over an item count++; } return count; } // @return entire rlp item byte length function _itemLength(uint256 memPtr) private pure returns (uint256) { uint256 itemLen; uint256 byte0; assembly { byte0 := byte(0, mload(memPtr)) } if (byte0 < STRING_SHORT_START) { itemLen = 1; } else if (byte0 < STRING_LONG_START) { itemLen = byte0 - STRING_SHORT_START + 1; } else if (byte0 < LIST_SHORT_START) { assembly { let byteLen := sub(byte0, 0xb7) // # of bytes the actual length is memPtr := add(memPtr, 1) // skip over the first byte /* 32 byte word size */ let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to get the len itemLen := add(dataLen, add(byteLen, 1)) } } else if (byte0 < LIST_LONG_START) { itemLen = byte0 - LIST_SHORT_START + 1; } else { assembly { let byteLen := sub(byte0, 0xf7) memPtr := add(memPtr, 1) let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to the correct length itemLen := add(dataLen, add(byteLen, 1)) } } return itemLen; } // @return number of bytes until the data function _payloadOffset(uint256 memPtr) private pure returns (uint256) { uint256 byte0; assembly { byte0 := byte(0, mload(memPtr)) } if (byte0 < STRING_SHORT_START) { return 0; } else if (byte0 < STRING_LONG_START || (byte0 >= LIST_SHORT_START && byte0 < LIST_LONG_START)) { return 1; } else if (byte0 < LIST_SHORT_START) { // being explicit return byte0 - (STRING_LONG_START - 1) + 1; } else { return byte0 - (LIST_LONG_START - 1) + 1; } } /* * @param src Pointer to source * @param dest Pointer to destination * @param len Amount of memory to copy from the source */ function copy(uint256 src, uint256 dest, uint256 len) private pure { if (len == 0) return; // copy as many word sizes as possible for (; len >= WORD_SIZE; len -= WORD_SIZE) { assembly { mstore(dest, mload(src)) } src += WORD_SIZE; dest += WORD_SIZE; } if (len > 0) { // left over bytes. Mask is used to remove unwanted bytes from the word uint256 mask = 256**(WORD_SIZE - len) - 1; assembly { let srcpart := and(mload(src), not(mask)) // zero out src let destpart := and(mload(dest), mask) // retrieve the bytes mstore(dest, or(destpart, srcpart)) } } } }
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
import {Initializable} from "../proxy/utils/Initializable.sol";
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract ContextUpgradeable is Initializable {
function __Context_init() internal onlyInitializing {
}
function __Context_init_unchained() internal onlyInitializing {
}
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC1967.sol)
pragma solidity ^0.8.20;
/**
* @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC.
*/
interface IERC1967 {
/**
* @dev Emitted when the implementation is upgraded.
*/
event Upgraded(address indexed implementation);
/**
* @dev Emitted when the admin account has changed.
*/
event AdminChanged(address previousAdmin, address newAdmin);
/**
* @dev Emitted when the beacon is changed.
*/
event BeaconUpgraded(address indexed beacon);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/StorageSlot.sol)
// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.
pragma solidity ^0.8.20;
/**
* @dev Library for reading and writing primitive types to specific storage slots.
*
* Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
* This library helps with reading and writing to such slots without the need for inline assembly.
*
* The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
*
* Example usage to set ERC-1967 implementation slot:
* ```solidity
* contract ERC1967 {
* // Define the slot. Alternatively, use the SlotDerivation library to derive the slot.
* bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
*
* function _getImplementation() internal view returns (address) {
* return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
* }
*
* function _setImplementation(address newImplementation) internal {
* require(newImplementation.code.length > 0);
* StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
* }
* }
* ```
*
* TIP: Consider using this library along with {SlotDerivation}.
*/
library StorageSlot {
struct AddressSlot {
address value;
}
struct BooleanSlot {
bool value;
}
struct Bytes32Slot {
bytes32 value;
}
struct Uint256Slot {
uint256 value;
}
struct Int256Slot {
int256 value;
}
struct StringSlot {
string value;
}
struct BytesSlot {
bytes value;
}
/**
* @dev Returns an `AddressSlot` with member `value` located at `slot`.
*/
function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
assembly ("memory-safe") {
r.slot := slot
}
}
/**
* @dev Returns a `BooleanSlot` with member `value` located at `slot`.
*/
function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
assembly ("memory-safe") {
r.slot := slot
}
}
/**
* @dev Returns a `Bytes32Slot` with member `value` located at `slot`.
*/
function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
assembly ("memory-safe") {
r.slot := slot
}
}
/**
* @dev Returns a `Uint256Slot` with member `value` located at `slot`.
*/
function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
assembly ("memory-safe") {
r.slot := slot
}
}
/**
* @dev Returns a `Int256Slot` with member `value` located at `slot`.
*/
function getInt256Slot(bytes32 slot) internal pure returns (Int256Slot storage r) {
assembly ("memory-safe") {
r.slot := slot
}
}
/**
* @dev Returns a `StringSlot` with member `value` located at `slot`.
*/
function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {
assembly ("memory-safe") {
r.slot := slot
}
}
/**
* @dev Returns an `StringSlot` representation of the string storage pointer `store`.
*/
function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {
assembly ("memory-safe") {
r.slot := store.slot
}
}
/**
* @dev Returns a `BytesSlot` with member `value` located at `slot`.
*/
function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {
assembly ("memory-safe") {
r.slot := slot
}
}
/**
* @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.
*/
function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {
assembly ("memory-safe") {
r.slot := store.slot
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC20.sol)
pragma solidity ^0.8.20;
import {IERC20} from "../token/ERC20/IERC20.sol";// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC165.sol)
pragma solidity ^0.8.20;
import {IERC165} from "../utils/introspection/IERC165.sol";// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/Errors.sol)
pragma solidity ^0.8.20;
/**
* @dev Collection of common custom errors used in multiple contracts
*
* IMPORTANT: Backwards compatibility is not guaranteed in future versions of the library.
* It is recommended to avoid relying on the error API for critical functionality.
*
* _Available since v5.1._
*/
library Errors {
/**
* @dev The ETH balance of the account is not enough to perform the operation.
*/
error InsufficientBalance(uint256 balance, uint256 needed);
/**
* @dev A call to an address target failed. The target may have reverted.
*/
error FailedCall();
/**
* @dev The deployment failed.
*/
error FailedDeployment();
/**
* @dev A necessary precompile is missing.
*/
error MissingPrecompile(address);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (proxy/Proxy.sol)
pragma solidity ^0.8.20;
/**
* @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM
* instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to
* be specified by overriding the virtual {_implementation} function.
*
* Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a
* different contract through the {_delegate} function.
*
* The success and return data of the delegated call will be returned back to the caller of the proxy.
*/
abstract contract Proxy {
/**
* @dev Delegates the current call to `implementation`.
*
* This function does not return to its internal call site, it will return directly to the external caller.
*/
function _delegate(address implementation) internal virtual {
assembly {
// Copy msg.data. We take full control of memory in this inline assembly
// block because it will not return to Solidity code. We overwrite the
// Solidity scratch pad at memory position 0.
calldatacopy(0, 0, calldatasize())
// Call the implementation.
// out and outsize are 0 because we don't know the size yet.
let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)
// Copy the returned data.
returndatacopy(0, 0, returndatasize())
switch result
// delegatecall returns 0 on error.
case 0 {
revert(0, returndatasize())
}
default {
return(0, returndatasize())
}
}
}
/**
* @dev This is a virtual function that should be overridden so it returns the address to which the fallback
* function and {_fallback} should delegate.
*/
function _implementation() internal view virtual returns (address);
/**
* @dev Delegates the current call to the address returned by `_implementation()`.
*
* This function does not return to its internal call site, it will return directly to the external caller.
*/
function _fallback() internal virtual {
_delegate(_implementation());
}
/**
* @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other
* function in the contract matches the call data.
*/
fallback() external payable virtual {
_fallback();
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/ERC20.sol)
pragma solidity ^0.8.20;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import {ContextUpgradeable} from "../../utils/ContextUpgradeable.sol";
import {IERC20Errors} from "@openzeppelin/contracts/interfaces/draft-IERC6093.sol";
import {Initializable} from "../../proxy/utils/Initializable.sol";
/**
* @dev Implementation of the {IERC20} interface.
*
* This implementation is agnostic to the way tokens are created. This means
* that a supply mechanism has to be added in a derived contract using {_mint}.
*
* TIP: For a detailed writeup see our guide
* https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
* to implement supply mechanisms].
*
* The default value of {decimals} is 18. To change this, you should override
* this function so it returns a different value.
*
* We have followed general OpenZeppelin Contracts guidelines: functions revert
* instead returning `false` on failure. This behavior is nonetheless
* conventional and does not conflict with the expectations of ERC-20
* applications.
*/
abstract contract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20, IERC20Metadata, IERC20Errors {
/// @custom:storage-location erc7201:openzeppelin.storage.ERC20
struct ERC20Storage {
mapping(address account => uint256) _balances;
mapping(address account => mapping(address spender => uint256)) _allowances;
uint256 _totalSupply;
string _name;
string _symbol;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.ERC20")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant ERC20StorageLocation = 0x52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace00;
function _getERC20Storage() private pure returns (ERC20Storage storage $) {
assembly {
$.slot := ERC20StorageLocation
}
}
/**
* @dev Sets the values for {name} and {symbol}.
*
* All two of these values are immutable: they can only be set once during
* construction.
*/
function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {
__ERC20_init_unchained(name_, symbol_);
}
function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {
ERC20Storage storage $ = _getERC20Storage();
$._name = name_;
$._symbol = symbol_;
}
/**
* @dev Returns the name of the token.
*/
function name() public view virtual returns (string memory) {
ERC20Storage storage $ = _getERC20Storage();
return $._name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() public view virtual returns (string memory) {
ERC20Storage storage $ = _getERC20Storage();
return $._symbol;
}
/**
* @dev Returns the number of decimals used to get its user representation.
* For example, if `decimals` equals `2`, a balance of `505` tokens should
* be displayed to a user as `5.05` (`505 / 10 ** 2`).
*
* Tokens usually opt for a value of 18, imitating the relationship between
* Ether and Wei. This is the default value returned by this function, unless
* it's overridden.
*
* NOTE: This information is only used for _display_ purposes: it in
* no way affects any of the arithmetic of the contract, including
* {IERC20-balanceOf} and {IERC20-transfer}.
*/
function decimals() public view virtual returns (uint8) {
return 18;
}
/**
* @dev See {IERC20-totalSupply}.
*/
function totalSupply() public view virtual returns (uint256) {
ERC20Storage storage $ = _getERC20Storage();
return $._totalSupply;
}
/**
* @dev See {IERC20-balanceOf}.
*/
function balanceOf(address account) public view virtual returns (uint256) {
ERC20Storage storage $ = _getERC20Storage();
return $._balances[account];
}
/**
* @dev See {IERC20-transfer}.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - the caller must have a balance of at least `value`.
*/
function transfer(address to, uint256 value) public virtual returns (bool) {
address owner = _msgSender();
_transfer(owner, to, value);
return true;
}
/**
* @dev See {IERC20-allowance}.
*/
function allowance(address owner, address spender) public view virtual returns (uint256) {
ERC20Storage storage $ = _getERC20Storage();
return $._allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* NOTE: If `value` is the maximum `uint256`, the allowance is not updated on
* `transferFrom`. This is semantically equivalent to an infinite approval.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function approve(address spender, uint256 value) public virtual returns (bool) {
address owner = _msgSender();
_approve(owner, spender, value);
return true;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Skips emitting an {Approval} event indicating an allowance update. This is not
* required by the ERC. See {xref-ERC20-_approve-address-address-uint256-bool-}[_approve].
*
* NOTE: Does not update the allowance if the current allowance
* is the maximum `uint256`.
*
* Requirements:
*
* - `from` and `to` cannot be the zero address.
* - `from` must have a balance of at least `value`.
* - the caller must have allowance for ``from``'s tokens of at least
* `value`.
*/
function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, value);
_transfer(from, to, value);
return true;
}
/**
* @dev Moves a `value` amount of tokens from `from` to `to`.
*
* This internal function is equivalent to {transfer}, and can be used to
* e.g. implement automatic token fees, slashing mechanisms, etc.
*
* Emits a {Transfer} event.
*
* NOTE: This function is not virtual, {_update} should be overridden instead.
*/
function _transfer(address from, address to, uint256 value) internal {
if (from == address(0)) {
revert ERC20InvalidSender(address(0));
}
if (to == address(0)) {
revert ERC20InvalidReceiver(address(0));
}
_update(from, to, value);
}
/**
* @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`
* (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding
* this function.
*
* Emits a {Transfer} event.
*/
function _update(address from, address to, uint256 value) internal virtual {
ERC20Storage storage $ = _getERC20Storage();
if (from == address(0)) {
// Overflow check required: The rest of the code assumes that totalSupply never overflows
$._totalSupply += value;
} else {
uint256 fromBalance = $._balances[from];
if (fromBalance < value) {
revert ERC20InsufficientBalance(from, fromBalance, value);
}
unchecked {
// Overflow not possible: value <= fromBalance <= totalSupply.
$._balances[from] = fromBalance - value;
}
}
if (to == address(0)) {
unchecked {
// Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.
$._totalSupply -= value;
}
} else {
unchecked {
// Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.
$._balances[to] += value;
}
}
emit Transfer(from, to, value);
}
/**
* @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).
* Relies on the `_update` mechanism
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* NOTE: This function is not virtual, {_update} should be overridden instead.
*/
function _mint(address account, uint256 value) internal {
if (account == address(0)) {
revert ERC20InvalidReceiver(address(0));
}
_update(address(0), account, value);
}
/**
* @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.
* Relies on the `_update` mechanism.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* NOTE: This function is not virtual, {_update} should be overridden instead
*/
function _burn(address account, uint256 value) internal {
if (account == address(0)) {
revert ERC20InvalidSender(address(0));
}
_update(account, address(0), value);
}
/**
* @dev Sets `value` as the allowance of `spender` over the `owner` s tokens.
*
* This internal function is equivalent to `approve`, and can be used to
* e.g. set automatic allowances for certain subsystems, etc.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `owner` cannot be the zero address.
* - `spender` cannot be the zero address.
*
* Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.
*/
function _approve(address owner, address spender, uint256 value) internal {
_approve(owner, spender, value, true);
}
/**
* @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.
*
* By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by
* `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any
* `Approval` event during `transferFrom` operations.
*
* Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to
* true using the following override:
*
* ```solidity
* function _approve(address owner, address spender, uint256 value, bool) internal virtual override {
* super._approve(owner, spender, value, true);
* }
* ```
*
* Requirements are the same as {_approve}.
*/
function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {
ERC20Storage storage $ = _getERC20Storage();
if (owner == address(0)) {
revert ERC20InvalidApprover(address(0));
}
if (spender == address(0)) {
revert ERC20InvalidSpender(address(0));
}
$._allowances[owner][spender] = value;
if (emitEvent) {
emit Approval(owner, spender, value);
}
}
/**
* @dev Updates `owner` s allowance for `spender` based on spent `value`.
*
* Does not update the allowance value in case of infinite allowance.
* Revert if not enough allowance is available.
*
* Does not emit an {Approval} event.
*/
function _spendAllowance(address owner, address spender, uint256 value) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance != type(uint256).max) {
if (currentAllowance < value) {
revert ERC20InsufficientAllowance(spender, currentAllowance, value);
}
unchecked {
_approve(owner, spender, currentAllowance - value, false);
}
}
}
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @notice Library for converting between addresses and bytes32 values.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/Bytes32AddressLib.sol)
library Bytes32AddressLib {
function fromLast20Bytes(bytes32 bytesValue) internal pure returns (address) {
return address(uint160(uint256(bytesValue)));
}
function fillLast12Bytes(address addressValue) internal pure returns (bytes32) {
return bytes32(bytes20(addressValue));
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC-165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[ERC].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/extensions/IERC20Metadata.sol)
pragma solidity ^0.8.20;
import {IERC20} from "../IERC20.sol";
/**
* @dev Interface for the optional metadata functions from the ERC-20 standard.
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (interfaces/draft-IERC6093.sol)
pragma solidity ^0.8.20;
/**
* @dev Standard ERC-20 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-20 tokens.
*/
interface IERC20Errors {
/**
* @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param balance Current balance for the interacting account.
* @param needed Minimum amount required to perform a transfer.
*/
error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC20InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC20InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.
* @param spender Address that may be allowed to operate on tokens without being their owner.
* @param allowance Amount of tokens a `spender` is allowed to operate with.
* @param needed Minimum amount required to perform a transfer.
*/
error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC20InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `spender` to be approved. Used in approvals.
* @param spender Address that may be allowed to operate on tokens without being their owner.
*/
error ERC20InvalidSpender(address spender);
}
/**
* @dev Standard ERC-721 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-721 tokens.
*/
interface IERC721Errors {
/**
* @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in ERC-20.
* Used in balance queries.
* @param owner Address of the current owner of a token.
*/
error ERC721InvalidOwner(address owner);
/**
* @dev Indicates a `tokenId` whose `owner` is the zero address.
* @param tokenId Identifier number of a token.
*/
error ERC721NonexistentToken(uint256 tokenId);
/**
* @dev Indicates an error related to the ownership over a particular token. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param tokenId Identifier number of a token.
* @param owner Address of the current owner of a token.
*/
error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC721InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC721InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `operator`’s approval. Used in transfers.
* @param operator Address that may be allowed to operate on tokens without being their owner.
* @param tokenId Identifier number of a token.
*/
error ERC721InsufficientApproval(address operator, uint256 tokenId);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC721InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `operator` to be approved. Used in approvals.
* @param operator Address that may be allowed to operate on tokens without being their owner.
*/
error ERC721InvalidOperator(address operator);
}
/**
* @dev Standard ERC-1155 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-1155 tokens.
*/
interface IERC1155Errors {
/**
* @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param balance Current balance for the interacting account.
* @param needed Minimum amount required to perform a transfer.
* @param tokenId Identifier number of a token.
*/
error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC1155InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC1155InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `operator`’s approval. Used in transfers.
* @param operator Address that may be allowed to operate on tokens without being their owner.
* @param owner Address of the current owner of a token.
*/
error ERC1155MissingApprovalForAll(address operator, address owner);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC1155InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `operator` to be approved. Used in approvals.
* @param operator Address that may be allowed to operate on tokens without being their owner.
*/
error ERC1155InvalidOperator(address operator);
/**
* @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.
* Used in batch transfers.
* @param idsLength Length of the array of token identifiers
* @param valuesLength Length of the array of token amounts
*/
error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);
}{
"remappings": [
"@openzeppelin-upgradeable/proxy/=lib/openzeppelin-contracts-upgradeable/contracts/proxy/",
"@openzeppelin-upgradeable/access/=lib/openzeppelin-contracts-upgradeable/contracts/access/",
"@openzeppelin-upgradeable/token/=lib/openzeppelin-contracts-upgradeable/contracts/token/",
"@openzeppelin-upgradeable/utils/=lib/openzeppelin-contracts-upgradeable/contracts/utils/",
"openzeppelin-contracts/contracts/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/",
"@openzeppelin/token/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/",
"@openzeppelin/proxy/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/proxy/",
"@openzeppelin/access/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/access/",
"@openzeppelin/interfaces/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/interfaces/",
"@openzeppelin/utils/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/",
"@openzeppelin/governance/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/governance/",
"@openzeppelin-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
"@openzeppelin/contracts/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/",
"@pythnetwork/=lib/pyth-sdk-solidity/",
"@money-market/=contracts/moneyMarket/src/",
"@money-market-scripts/=contracts/moneyMarket/scripts/",
"@money-market-tests/=contracts/moneyMarket/tests/",
"@contracts/=contracts/",
"solidity-utils/=lib/solidity-utils/src/",
"@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
"ds-test/=lib/solmate/lib/ds-test/src/",
"erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/",
"forge-std/=lib/forge-std/src/",
"halmos-cheatcodes/=lib/openzeppelin-contracts-upgradeable/lib/halmos-cheatcodes/src/",
"openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
"pyth-sdk-solidity/=lib/pyth-sdk-solidity/",
"solmate/=lib/solmate/src/"
],
"optimizer": {
"enabled": true,
"runs": 200
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "prague",
"viaIR": false
}Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[{"internalType":"address","name":"implementation","type":"address"}],"name":"ERC1967InvalidImplementation","type":"error"},{"inputs":[],"name":"ERC1967NonPayable","type":"error"},{"inputs":[],"name":"ExternalFillNotAllowed","type":"error"},{"inputs":[],"name":"FailedCall","type":"error"},{"inputs":[],"name":"FillAlreadyExists","type":"error"},{"inputs":[],"name":"IntentAlreadyExists","type":"error"},{"inputs":[],"name":"IntentNotFound","type":"error"},{"inputs":[],"name":"InvalidAmount","type":"error"},{"inputs":[],"name":"InvalidInitialization","type":"error"},{"inputs":[],"name":"InvalidOutputToken","type":"error"},{"inputs":[],"name":"InvalidSolver","type":"error"},{"inputs":[],"name":"NotInitializing","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"PartialFillNotAllowed","type":"error"},{"inputs":[],"name":"PendingFillExists","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"inputs":[],"name":"SpokeNotConfigured","type":"error"},{"inputs":[],"name":"TransferFailed","type":"error"},{"inputs":[],"name":"UUPSUnauthorizedCallContext","type":"error"},{"inputs":[{"internalType":"bytes32","name":"slot","type":"bytes32"}],"name":"UUPSUnsupportedProxiableUUID","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"fillId","type":"uint256"},{"components":[{"internalType":"bytes32","name":"intentHash","type":"bytes32"},{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"inputAmount","type":"uint256"},{"internalType":"uint256","name":"outputAmount","type":"uint256"}],"indexed":false,"internalType":"struct Intents.ExternalFill","name":"fill","type":"tuple"}],"name":"ExternalFillFailed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"version","type":"uint64"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"intentHash","type":"bytes32"}],"name":"IntentCancelled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"intentHash","type":"bytes32"},{"components":[{"internalType":"uint256","name":"intentId","type":"uint256"},{"internalType":"address","name":"creator","type":"address"},{"internalType":"address","name":"inputToken","type":"address"},{"internalType":"address","name":"outputToken","type":"address"},{"internalType":"uint256","name":"inputAmount","type":"uint256"},{"internalType":"uint256","name":"minOutputAmount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"allowPartialFill","type":"bool"},{"internalType":"uint256","name":"srcChain","type":"uint256"},{"internalType":"uint256","name":"dstChain","type":"uint256"},{"internalType":"bytes","name":"srcAddress","type":"bytes"},{"internalType":"bytes","name":"dstAddress","type":"bytes"},{"internalType":"address","name":"solver","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"indexed":false,"internalType":"struct Intents.Intent","name":"intent","type":"tuple"}],"name":"IntentCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"intentHash","type":"bytes32"},{"components":[{"internalType":"bool","name":"exists","type":"bool"},{"internalType":"uint256","name":"remainingInput","type":"uint256"},{"internalType":"uint256","name":"receivedOutput","type":"uint256"},{"internalType":"bool","name":"pendingPayment","type":"bool"}],"indexed":false,"internalType":"struct Intents.IntentState","name":"intentState","type":"tuple"}],"name":"IntentFilled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"inputs":[],"name":"HUB_CHAIN_ID","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NATIVE_TOKEN","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UPGRADE_INTERFACE_VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"chainID","type":"uint256"},{"internalType":"bytes","name":"spokeAddress","type":"bytes"}],"name":"addSpoke","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"assetManager","outputs":[{"internalType":"contract IAssetManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"intentId","type":"uint256"},{"internalType":"address","name":"creator","type":"address"},{"internalType":"address","name":"inputToken","type":"address"},{"internalType":"address","name":"outputToken","type":"address"},{"internalType":"uint256","name":"inputAmount","type":"uint256"},{"internalType":"uint256","name":"minOutputAmount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"allowPartialFill","type":"bool"},{"internalType":"uint256","name":"srcChain","type":"uint256"},{"internalType":"uint256","name":"dstChain","type":"uint256"},{"internalType":"bytes","name":"srcAddress","type":"bytes"},{"internalType":"bytes","name":"dstAddress","type":"bytes"},{"internalType":"address","name":"solver","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct Intents.Intent","name":"intent","type":"tuple"}],"name":"cancelIntent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"connection","outputs":[{"internalType":"contract IConnection","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"intentId","type":"uint256"},{"internalType":"address","name":"creator","type":"address"},{"internalType":"address","name":"inputToken","type":"address"},{"internalType":"address","name":"outputToken","type":"address"},{"internalType":"uint256","name":"inputAmount","type":"uint256"},{"internalType":"uint256","name":"minOutputAmount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"allowPartialFill","type":"bool"},{"internalType":"uint256","name":"srcChain","type":"uint256"},{"internalType":"uint256","name":"dstChain","type":"uint256"},{"internalType":"bytes","name":"srcAddress","type":"bytes"},{"internalType":"bytes","name":"dstAddress","type":"bytes"},{"internalType":"address","name":"solver","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct Intents.Intent","name":"intent","type":"tuple"}],"name":"createIntent","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"externalFills","outputs":[{"internalType":"bytes32","name":"intentHash","type":"bytes32"},{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"inputAmount","type":"uint256"},{"internalType":"uint256","name":"outputAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"intentId","type":"uint256"},{"internalType":"address","name":"creator","type":"address"},{"internalType":"address","name":"inputToken","type":"address"},{"internalType":"address","name":"outputToken","type":"address"},{"internalType":"uint256","name":"inputAmount","type":"uint256"},{"internalType":"uint256","name":"minOutputAmount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"allowPartialFill","type":"bool"},{"internalType":"uint256","name":"srcChain","type":"uint256"},{"internalType":"uint256","name":"dstChain","type":"uint256"},{"internalType":"bytes","name":"srcAddress","type":"bytes"},{"internalType":"bytes","name":"dstAddress","type":"bytes"},{"internalType":"address","name":"solver","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct Intents.Intent","name":"intent","type":"tuple"},{"internalType":"uint256","name":"_inputAmount","type":"uint256"},{"internalType":"uint256","name":"_outputAmount","type":"uint256"},{"internalType":"uint256","name":"_externalFillId","type":"uint256"}],"name":"fillIntent","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"intentHash","type":"bytes32"},{"internalType":"bytes","name":"spokeTokenAddress","type":"bytes"},{"internalType":"uint256","name":"_outputAmount","type":"uint256"},{"internalType":"uint256","name":"_externalFillId","type":"uint256"},{"internalType":"bytes","name":"dstAddress","type":"bytes"},{"internalType":"uint256","name":"dstChain","type":"uint256"}],"name":"fillIntentTest","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"getImplementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IWalletFactory","name":"_walletFactory","type":"address"},{"internalType":"contract IAssetManager","name":"_assetManager","type":"address"},{"internalType":"contract IConnection","name":"_connection","type":"address"},{"internalType":"uint256","name":"_HUB_CHAIN_ID","type":"uint256"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"intentStates","outputs":[{"internalType":"bool","name":"exists","type":"bool"},{"internalType":"uint256","name":"remainingInput","type":"uint256"},{"internalType":"uint256","name":"receivedOutput","type":"uint256"},{"internalType":"bool","name":"pendingPayment","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"partnerFee","outputs":[{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"pendingIntentStates","outputs":[{"internalType":"uint256","name":"pendingInput","type":"uint256"},{"internalType":"uint256","name":"pendingOutput","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"pendingPayouts","outputs":[{"internalType":"address","name":"solver","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"intentId","type":"uint256"},{"internalType":"address","name":"creator","type":"address"},{"internalType":"address","name":"inputToken","type":"address"},{"internalType":"address","name":"outputToken","type":"address"},{"internalType":"uint256","name":"inputAmount","type":"uint256"},{"internalType":"uint256","name":"minOutputAmount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"allowPartialFill","type":"bool"},{"internalType":"uint256","name":"srcChain","type":"uint256"},{"internalType":"uint256","name":"dstChain","type":"uint256"},{"internalType":"bytes","name":"srcAddress","type":"bytes"},{"internalType":"bytes","name":"dstAddress","type":"bytes"},{"internalType":"address","name":"solver","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct Intents.Intent","name":"intent","type":"tuple"},{"internalType":"uint256","name":"_inputAmount","type":"uint256"},{"internalType":"uint256","name":"_outputAmount","type":"uint256"},{"internalType":"uint256","name":"_externalFillId","type":"uint256"}],"name":"preFillIntent","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"proxiableUUID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"srcChainId","type":"uint256"},{"internalType":"bytes","name":"srcAddress","type":"bytes"},{"internalType":"uint256","name":"connSn","type":"uint256"},{"internalType":"bytes","name":"payload","type":"bytes"},{"internalType":"bytes[]","name":"signatures","type":"bytes[]"}],"name":"recvMessage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"registerMe","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"solver","type":"address"},{"internalType":"bool","name":"whitelisted","type":"bool"}],"name":"setWhitelistedSolver","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"spokes","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"upgradeToAndCall","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"walletFactory","outputs":[{"internalType":"contract IWalletFactory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"whitelistedSolvers","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
60a060405230608052348015610013575f5ffd5b5061001c610021565b6100d3565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff16156100715760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b03908116146100d05780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b608051614e746100f95f395f81816120cc015281816120f501526122340152614e745ff3fe6080604052600436106101d3575f3560e01c80638da5cb5b116100fd578063cf756fdf11610092578063e5795fd611610062578063e5795fd614610620578063ea6ced191461063f578063f2fde38b1461065e578063fd19016c1461067d575f5ffd5b8063cf756fdf146105c5578063d3da3330146105e4578063d971729f146105f9578063e30c39781461060c575f5ffd5b8063ad3cb1cc116100cd578063ad3cb1cc14610538578063c5c0369914610575578063ca25d31914610593578063cd01a9b0146105b2575f5ffd5b80638da5cb5b146104dd57806394217ad1146104f15780639a198d6114610510578063aaf10f4214610524575f5ffd5b80634f1ef28611610173578063715018a611610143578063715018a61461041f57806372f63f091461043357806379ba50971461048b57806388df70361461049f575f5ffd5b80634f1ef2861461036257806352d1902d14610375578063552800ac146103975780635ff8a66b146103b6575f5ffd5b806336cbe9e5116101ae57806336cbe9e51461023657806338e42f54146102be5780634b2b20e7146103055780634d88df2b14610324575f5ffd5b8063016f02e3146101de57806331f7d964146101f35780633468af4614610223575f5ffd5b366101da57005b5f5ffd5b6101f16101ec366004613e78565b61069c565b005b3480156101fe575f5ffd5b506102065f81565b6040516001600160a01b0390911681526020015b60405180910390f35b6101f1610231366004613ea9565b610a0f565b348015610241575f5ffd5b5061028a610250366004613ef8565b60056020525f90815260409020805460018201546002830154600384015460049094015492936001600160a01b0392831693929091169185565b604080519586526001600160a01b03948516602087015292909316918401919091526060830152608082015260a00161021a565b3480156102c9575f5ffd5b506102f06102d8366004613ef8565b60086020525f90815260409020805460019091015482565b6040805192835260208301919091520161021a565b348015610310575f5ffd5b506101f161031f36600461405c565b610b60565b34801561032f575f5ffd5b5061035261033e366004614157565b60076020525f908152604090205460ff1681565b604051901515815260200161021a565b6101f1610370366004614172565b610e38565b348015610380575f5ffd5b50610389610e57565b60405190815260200161021a565b3480156103a2575f5ffd5b506101f16103b13660046141d6565b610e72565b3480156103c1575f5ffd5b506103fb6103d0366004613ef8565b60046020525f9081526040902080546001820154600283015460039093015460ff9283169391921684565b6040805194151585526020850193909352918301521515606082015260800161021a565b34801561042a575f5ffd5b506101f1610ea4565b34801561043e575f5ffd5b5061046e61044d366004613ef8565b600a6020525f9081526040902080546001909101546001600160a01b031682565b604080519283526001600160a01b0390911660208301520161021a565b348015610496575f5ffd5b506101f1610eb7565b3480156104aa575f5ffd5b506104be6104b936600461420d565b610efc565b604080516001600160a01b03909316835260208301919091520161021a565b3480156104e8575f5ffd5b50610206610f3e565b3480156104fc575f5ffd5b50600154610206906001600160a01b031681565b34801561051b575f5ffd5b506101f1610f72565b34801561052f575f5ffd5b5061020661105b565b348015610543575f5ffd5b50610568604051806040016040528060058152602001640352e302e360dc1b81525081565b60405161021a919061425b565b348015610580575f5ffd5b505f54610206906001600160a01b031681565b34801561059e575f5ffd5b506101f16105ad366004613e78565b61107f565b6101f16105c036600461426d565b611402565b3480156105d0575f5ffd5b506101f16105df3660046142f5565b611565565b3480156105ef575f5ffd5b5061038960035481565b6101f1610607366004613ea9565b6116bd565b348015610617575f5ffd5b50610206611746565b34801561062b575f5ffd5b506101f161063a366004614343565b61176e565b34801561064a575f5ffd5b50610568610659366004613ef8565b611792565b348015610669575f5ffd5b506101f1610678366004614157565b611829565b348015610688575f5ffd5b50600254610206906001600160a01b031681565b6106a46118ae565b5f816040516020016106b6919061450a565b6040516020818303038152906040528051906020012090505f6106d8836118e5565b6020810151519091506001600160a01b03161561083e57336107006040850160208601614157565b6001600160a01b0316146107545760405162461bcd60e51b815260206004820152601660248201527521b932b0ba37b91036bab9ba1031329039b2b73232b960511b60448201526064015b60405180910390fd5b5f6107656060850160408601614157565b6001600160a01b0316036107d95760405162461bcd60e51b815260206004820152603560248201527f4e617469766520746f6b656e2063616e6e6f74206265207573656420617320696044820152746e70757420746f6b656e207769746820686f6f6b7360581b606482015260840161074b565b6020810151516040516307e7152560e41b81526001600160a01b0390911690637e7152509061080c90869060040161450a565b5f604051808303815f87803b158015610823575f5ffd5b505af1158015610835573d5f5f3e3d5ffd5b50505050610869565b8051516108676108546060860160408701614157565b610862836080880135614530565b611963565b505b5f828152600460209081526040918290208251608081018452815460ff9081161515808352600184015494830194909452600283015494820194909452600390910154909216151560608301526108e6575060408051608080820183526001825285013560208201525f918101829052606081019190915261092d565b80606001511561091457610909836109046060870160408801614157565b6119c6565b5f606082015261092d565b6040516302b000c160e21b815260040160405180910390fd5b7f29fecd55cf4a8b6d0aaf6870fbab480f04c3caab050a1af7654278af363cd96f838560405161095e929190614543565b60405180910390a180602001515f036109a6575f838152600460205260408120805460ff199081168255600182018390556002820192909255600301805490911690556109f3565b5f838152600460209081526040918290208351815490151560ff19918216178255918401516001820155918301516002830155606083015160039092018054921515929091169190911790555b505050610a0c60015f516020614e1f5f395f51905f5255565b50565b610a176118ae565b5f84604051602001610a29919061450a565b60408051601f1981840301815291815281516020928301205f818152600490935290822090925090610a5a876118e5565b60200151516001600160a01b031614610ac45760405162461bcd60e51b815260206004820152602660248201527f486f6f6b7320617265206e6f7420616c6c6f77656420746f206265207072652d604482015265199a5b1b195960d21b606482015260840161074b565b805460ff16610b3557604080516080808201835260018083529089013560208084019182525f8486018181526060860185815289835260049093529590209351845490151560ff19918216178555915192840192909255925160028301555160039091018054911515919092161790555b610b428683878787611a54565b5050610b5a60015f516020614e1f5f395f51905f5255565b50505050565b610b686118ae565b60025460405163372ff73f60e21b81526001600160a01b039091169063dcbfdcfc90610ba4908a908a908a908a908a908a908a9060040161455b565b5f604051808303815f87803b158015610bbb575f5ffd5b505af1158015610bcd573d5f5f3e3d5ffd5b5050505f88815260066020526040908190209051610beb925061462c565b60405180910390208686604051610c03929190614699565b604051809103902014610c14575f5ffd5b5f610c1e84611dd9565b80515f908152600560208181526040808420815160a081018352815481526001808301546001600160a01b0390811683870152600280850154909116838601526003808501546060850190815260049586015460808601528a518a5297875285892089815592830180546001600160a01b0319908116909155918301805490921690915581018790559091018590558051808652600890935290842092518354959650909491939091839190610cd59084906146a8565b909155505060808301516001820180545f90610cf29084906146a8565b909155505080545f03610d18575f82815260086020526040812081815560010155610d33565b5f828152600860205260409020815481556001808301549101555b8360200151610db85783516040805191825284516020808401919091528501516001600160a01b0390811683830152858201511660608084019190915285015160808084019190915285015160a0830152517f903cf0a603920e4f3e45542f8960563511f94eba7d94077a61067e409cd3e1e19181900360c00190a150505050610e19565b5f828152600460209081526040808320606087015160808801518884015189860151600a875296859020855180870190965280548652600101546001600160a01b0316958501959095529194610e1394889487949290611e7d565b50505050505b610e2f60015f516020614e1f5f395f51905f5255565b50505050505050565b610e406120c1565b610e4982612165565b610e53828261216d565b5050565b5f610e60612229565b505f516020614dff5f395f51905f5290565b610e7a612272565b6001600160a01b03919091165f908152600760205260409020805460ff1916911515919091179055565b610eac612272565b610eb55f6122a4565b565b3380610ec1611746565b6001600160a01b031614610ef35760405163118cdaa760e01b81526001600160a01b038216600482015260240161074b565b610a0c816122a4565b6009602052815f5260405f208181548110610f15575f80fd5b5f918252602090912060029091020180546001909101546001600160a01b039091169250905082565b5f807f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c1993005b546001600160a01b031692915050565b604051609e60248201525f9073dc2b0d2dd2b7759d97d50db4eabdc369731108309060440160408051601f198184030181529181526020820180516001600160e01b03166307983f4560e21b17905251610fcc91906146bb565b5f604051808303815f865af19150503d805f8114611005576040519150601f19603f3d011682016040523d82523d5f602084013e61100a565b606091505b5050905080610a0c5760405162461bcd60e51b815260206004820152601860248201527f4665654d20726567697374726174696f6e206661696c65640000000000000000604482015260640161074b565b5f61107a5f516020614dff5f395f51905f52546001600160a01b031690565b905090565b6110876118ae565b5f81604051602001611099919061450a565b60408051601f1981840301815291815281516020928301205f818152600484528281206008909452918220600184015491945091036110eb576040516361ae648360e01b815260040160405180910390fd5b60018101541561110e5760405163bd10ceab60e01b815260040160405180910390fd5b61111e6040850160208601614157565b6001600160a01b0316336001600160a01b03161415801561114f575060c0840135158061114f57508360c001354211155b801561119d575060408051608081018252835460ff908116151582526001850154602083015260028501549282019290925260038401549091161515606082015261119b9085906122dc565b155b156111ba576040516282b42960e81b815260040160405180910390fd5b60018201541561137f575f6111ce856118e5565b90505f836001015486608001356111e591906146a8565b8251602001519091505f906001600160a01b031615801590611208575082515115155b1561122e578251516080880135906112219084906146d1565b61122b91906146fc565b90505b8015611253576112536112476060890160408a01614157565b845160200151836123f5565b8251515f906112639083906146a8565b90505f8187600101546112769190614530565b5f898152600a602090815260408220918255600190910180546001600160a01b0319169055860151519091506001600160a01b03161561131757602085015151604051639645380760e01b81526001600160a01b03909116906396453807906112e5908c90859060040161470f565b5f604051808303815f87803b1580156112fc575f5ffd5b505af115801561130e573d5f5f3e3d5ffd5b50505050611379565b61137961132a60608b0160408c01614157565b6101008b013561133e6101408d018d614730565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152508792506124a7915050565b50505050505b5f83815260046020526040808220805460ff1990811682556001820184905560028201939093556003018054909216909155517fc08eb64db16a39d2848960af04e3f16fb404d9d436a9f0e9d7d0d4854715c9dc906113e19085815260200190565b60405180910390a1505050610a0c60015f516020614e1f5f395f51905f5255565b5f818152600660205260408120805461141a906145fa565b80601f0160208091040260200160405190810160405280929190818152602001828054611446906145fa565b80156114915780601f1061146857610100808354040283529160200191611491565b820191905f5260205f20905b81548152906001019060200180831161147457829003601f168201915b505050505090505f6040518060c00160405280868152602001896040516020016114bd91815260200190565b60408051601f1981840301815291905281526020016114db33612611565b815260208101869052604081018990526060018790526002549091506001600160a01b0316636ea9cec9848461151085612647565b6040518463ffffffff1660e01b815260040161152e93929190614772565b5f604051808303815f87803b158015611545575f5ffd5b505af1158015611557573d5f5f3e3d5ffd5b505050505050505050505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff1615906001600160401b03165f811580156115a95750825b90505f826001600160401b031660011480156115c45750303b155b9050811580156115d2575080155b156115f05760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561161a57845460ff60401b1916600160401b1785555b61162333612788565b61162b612799565b5f80546001600160a01b03808c166001600160a01b031992831617909255600180548b841690831617905560028054928a1692909116919091179055600386905583156116b257845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050505050565b6116c56118ae565b5f846040516020016116d7919061450a565b60408051601f1981840301815291815281516020928301205f8181526004909352912080549192509060ff16611720576040516361ae648360e01b815260040160405180910390fd5b600381015460ff1615610b35576040516361ae648360e01b815260040160405180910390fd5b5f807f237e158222e3e6968b72b9db0d8043aacf074ad9f650f0d1606b4d82ee432c00610f62565b611776612272565b5f82815260066020526040902061178d82826147e0565b505050565b60066020525f9081526040902080546117aa906145fa565b80601f01602080910402602001604051908101604052809291908181526020018280546117d6906145fa565b80156118215780601f106117f857610100808354040283529160200191611821565b820191905f5260205f20905b81548152906001019060200180831161180457829003601f168201915b505050505081565b611831612272565b7f237e158222e3e6968b72b9db0d8043aacf074ad9f650f0d1606b4d82ee432c0080546001600160a01b0319166001600160a01b0383169081178255611875610f3e565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a35050565b5f516020614e1f5f395f51905f528054600119016118df57604051633ee5aeb560e01b815260040160405180910390fd5b60029055565b6118ed613dda565b6118fb6101a0830183614730565b90505f03611947575050604080516080810182525f8183018181526060830182905282528251808401845281815283516020818101909552918252808401919091529181019190915290565b61195d6119586101a0840184614730565b6127a1565b92915050565b805f036119835760405163162908e360e11b815260040160405180910390fd5b6001600160a01b0382166119b157803414610e535760405163162908e360e11b815260040160405180910390fd5b610e536001600160a01b03831633308461291d565b5f828152600960205260408120905b8154811015611a3d575f8282815481106119f1576119f161489a565b5f9182526020918290206040805180820190915260029092020180546001600160a01b0316808352600190910154928201839052909250611a34918691906123f5565b506001016119d5565b505f83815260096020526040812061178d91613e25565b5f848152600460209081526040808320600890925282209091611a76886118e5565b51835490915060ff16611a9c576040516361ae648360e01b815260040160405180910390fd5b815460018401545f91611aae916146a8565b905080871115611ad15760405163162908e360e11b815260040160405180910390fd5b8087108015611aee5750611aec6101008a0160e08b016148ae565b155b15611b0c576040516323bc005f60e21b815260040160405180910390fd5b5f611b1f6101a08b016101808c01614157565b6001600160a01b031614158015611b50575033611b446101a08b016101808c01614157565b6001600160a01b031614155b15611b6e5760405163af24067760e01b815260040160405180910390fd5b5f60808a0135611b8260a08c01358a6146d1565b611b8c91906146fc565b905080871015611baf5760405163162908e360e11b815260040160405180910390fd5b5f611bb98b6118e5565b90508615611bda57611bcf8b8b8b8b8b86612984565b505050505050611dd2565b611bf3611bed60808d0160608e01614157565b89611963565b611c55611c0660808d0160608e01614157565b6101208d0135611c1a6101608f018f614730565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152508e92506124a7915050565b6020810151516001600160a01b031615611da857600386015460ff1615611cb55760405162461bcd60e51b815260206004820152601460248201527343616e6e6f742070726566696c6c20686f6f6b7360601b604482015260640161074b565b60408051608081018252875460ff90811615158252600189015460208301526002890154928201929092526003880154909116151560608201525f90611cfd908d908c612db4565b6020830151519091506001600160a01b031663d4ef80518d89611d20858f614530565b8d6040518563ffffffff1660e01b8152600401611d4094939291906148c9565b5f604051808303815f87803b158015611d57575f5ffd5b505af1158015611d69573d5f5f3e3d5ffd5b505050602083015151611da6915030611d82848e614530565b8f6040016020810190611d959190614157565b6001600160a01b031692919061291d565b505b611dcb8a878b8b8f6040016020810190611dc29190614157565b86513390611e7d565b5050505050505b5050505050565b6040805180820182525f8082526020808301829052835180850185528281528101829052835180850190945284518452848101908401529091611e1b90612e62565b90506040518060400160405280611e4a835f81518110611e3d57611e3d61489a565b6020026020010151612f67565b8152602001611e7283600181518110611e6557611e6561489a565b6020026020010151612fb2565b151590529392505050565b83866002015f828254611e909190614530565b9250508190555084866001015f828254611eaa91906146a8565b90915550506040517f179edcc2ff551e1336d178824736b025cc5df1a59d05fbcb69ae2de8c06433da90611ee1908990899061491e565b60405180910390a160018601545f908103611f1b575080515f888152600a6020526040812090815560010180546001600160a01b03191690555b6001870154158015611f325750600387015460ff16155b15611f6c575f888152600460205260408120805460ff19908116825560018201839055600282019290925560030180549091169055611fba565b5f8881526004602052604090208754815460ff918216151560ff199182161783556001808b0154908401556002808b0154908401556003808b01549301805493909216151592169190911790555b600387015460ff1615612097575f88815260096020908152604080832081518083019092526001600160a01b0387811683528284018b8152825460018082018555938752949095209251600290940290920180546001600160a01b0319169390921692909217815591519101558015612092575f8881526009602090815260408083208151808301909252858301516001600160a01b039081168352828401868152825460018082018555938752949095209251600290940290920180546001600160a01b0319169390921692909217815591519101555b6120b7565b6120a28484886123f5565b80156120b7576120b7848360200151836123f5565b5050505050505050565b306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016148061214757507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031661213b5f516020614dff5f395f51905f52546001600160a01b031690565b6001600160a01b031614155b15610eb55760405163703e46dd60e11b815260040160405180910390fd5b610a0c612272565b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156121c7575060408051601f3d908101601f191682019092526121c491810190614959565b60015b6121ef57604051634c9c8ce360e01b81526001600160a01b038316600482015260240161074b565b5f516020614dff5f395f51905f52811461221f57604051632a87526960e21b81526004810182905260240161074b565b61178d8383612ff0565b306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610eb55760405163703e46dd60e11b815260040160405180910390fd5b3361227b610f3e565b6001600160a01b031614610eb55760405163118cdaa760e01b815233600482015260240161074b565b7f237e158222e3e6968b72b9db0d8043aacf074ad9f650f0d1606b4d82ee432c0080546001600160a01b0319168155610e5382613045565b5f5f6122e7846118e5565b602080820151519192506123019060408701908701614157565b6001600160a01b0316336001600160a01b031614158015612332575060c0850135158061233257508460c001354211155b156123eb576001600160a01b038116156123eb575f61236085866020015188612db49092919063ffffffff16565b856020015161236f9190614530565b6040516354874b1560e11b81529091506001600160a01b0383169063a90e962a906123a290899089908690600401614970565b602060405180830381865afa1580156123bd573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906123e191906149bb565b935050505061195d565b505f949350505050565b805f036124155760405163162908e360e11b815260040160405180910390fd5b6001600160a01b038316612493575f826001600160a01b0316826040515f6040518083038185875af1925050503d805f811461246c576040519150601f19603f3d011682016040523d82523d5f602084013e612471565b606091505b5050905080610b5a576040516312171d8360e31b815260040160405180910390fd5b61178d6001600160a01b03841683836130b5565b805f036124c75760405163162908e360e11b815260040160405180910390fd5b60035483036124e8576124e3846124dd846130e6565b836123f5565b610b5a565b600154604051634586e5a760e11b81526001600160a01b0386811660048301525f921690638b0dcb4e906024015f60405180830381865afa15801561252f573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526125569190810190614a23565b5090508084146125b45760405162461bcd60e51b8152602060048201526024808201527f496e76616c69642064657374696e6174696f6e2061646472657373206f72207460448201526337b5b2b760e11b606482015260840161074b565b60015460405163c6b4180b60e01b81526001600160a01b039091169063c6b4180b906125e890889087908790600401614a5d565b5f604051808303815f87803b1580156125ff575f5ffd5b505af11580156116b2573d5f5f3e3d5ffd5b604051606082811b6bffffffffffffffffffffffff19166020830152906034016040516020818303038152906040529050919050565b60408051600680825260e082019092526060915f9190816020015b6060815260200190600190039081612662575050835190915061268490613136565b815f815181106126965761269661489a565b60200260200101819052506126ae8360200151613144565b816001815181106126c1576126c161489a565b60200260200101819052506126d98360400151613144565b816002815181106126ec576126ec61489a565b60200260200101819052506127048360600151613144565b816003815181106127175761271761489a565b602002602001018190525061272f8360800151613144565b816004815181106127425761274261489a565b602002602001018190525061275a8360a00151613136565b8160058151811061276d5761276d61489a565b602002602001018190525061278181613192565b9392505050565b6127906131b5565b610a0c816131fe565b610eb56131b5565b6127a9613dda565b5f8290036127f65750604080516080810182525f8183018181526060830182905282528251808401845281815283516020818101909552918252808401919091529181019190915261195d565b5f612801848461322f565b9050600160ff16815f015160ff160361285857604051806040016040528061282c8360200151613307565b81526040805180820182525f8082528251602081810190945290815281830152910152915061195d9050565b805160ff16600119016128ab57604051806040016040528060405180604001604052805f81526020015f6001600160a01b031681525081526020016128a0836020015161332e565b81525091505061195d565b805160ff166128d6575f6128c28260200151613356565b90506128cd81613379565b9250505061195d565b5050604080516080810182525f8183018181526060830182905282528251808401845281815283516020818101909552918252808401919091529181019190915292915050565b6040516001600160a01b038481166024830152838116604483015260648201839052610b5a9186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b03838183161783525050505061347b565b335f9081526007602052604090205460ff166129b2576040516282b42960e81b815260040160405180910390fd5b6020810151516001600160a01b0316156129df5760405163135d8d3b60e21b815260040160405180910390fd5b6101208601355f90815260066020526040812080546129fd906145fa565b80601f0160208091040260200160405190810160405280929190818152602001828054612a29906145fa565b8015612a745780601f10612a4b57610100808354040283529160200191612a74565b820191905f5260205f20905b815481529060010190602001808311612a5757829003601f168201915b5050505050905080515f03612a9c57604051630e16ee5960e21b815260040160405180910390fd5b5f8381526005602052604090206004015415612acb57604051638b7071a960e01b815260040160405180910390fd5b6001545f9081906001600160a01b0316638b0dcb4e612af060808c0160608d01614157565b6040516001600160e01b031960e084901b1681526001600160a01b0390911660048201526024015f60405180830381865afa158015612b31573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052612b589190810190614a23565b915091508861012001358214612b80576040516231010160e51b815260040160405180910390fd5b5f888152600860205260408120805490918991839190612ba1908490614530565b9250508190555086816001015f828254612bbb9190614530565b90915550505f89815260086020908152604080832084548155600180860154918101919091558851600a84528285208151815590840151910180546001600160a01b0319166001600160a01b03909216919091179055805160c08101825289815281518084018e905290928301910160408051601f198184030181529190528152602001612c4833612611565b8152602001612c5b6101608e018e614730565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250505090825250602080820186905260409182018b9052815160a0810183528d8152339181019190915291925081810190612ccb9060608f01908f01614157565b6001600160a01b03908116825260208083018d905260409283018c90525f8b81526005825283902084518155908401516001820180549184166001600160a01b031992831617905592840151600280830180549285169290951691909117909355606084015160038201556080909301516004909301929092555416636ea9cec96101208d013587612d5c85612647565b6040518463ffffffff1660e01b8152600401612d7a93929190614772565b5f604051808303815f87803b158015612d91575f5ffd5b505af1158015612da3573d5f5f3e3d5ffd5b505050505050505050505050505050565b5f5f612dbf856118e5565b5180519091501580612ddc575060208101516001600160a01b0316155b15612dea575f915050612781565b60208401516080860135905f90612e0190836146a8565b90505f612e0e8683614530565b90505f8383865f0151612e2191906146d1565b612e2b91906146fc565b90505f8483875f0151612e3e91906146d1565b612e4891906146fc565b9050612e5482826146a8565b9a9950505050505050505050565b6060612e6d826134e7565b612e75575f5ffd5b5f612e7f83613514565b90505f816001600160401b03811115612e9a57612e9a613f0f565b604051908082528060200260200182016040528015612ede57816020015b604080518082019091525f8082526020820152815260200190600190039081612eb85790505b5090505f612eef8560200151613597565b8560200151612efe9190614530565b90505f805b84811015612f5c57612f1483613616565b9150604051806040016040528083815260200184815250848281518110612f3d57612f3d61489a565b6020908102919091010152612f528284614530565b9250600101612f03565b509195945050505050565b80515f9015801590612f7b57508151602110155b612f83575f5ffd5b5f5f612f8e846136be565b815191935091506020821015612faa5760208290036101000a90045b949350505050565b80515f90600114612fc1575f5ffd5b602082015180515f1a90811580612fd85750608082145b15612fe657505f9392505050565b5060019392505050565b612ff982613700565b6040516001600160a01b038316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a280511561303d5761178d8282613763565b610e536137d5565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b6040516001600160a01b0383811660248301526044820183905261178d91859182169063a9059cbb90606401612952565b5f815160141461312e5760405162461bcd60e51b8152602060048201526013602482015272092dcecc2d8d2c840c8c2e8c240d8cadccee8d606b1b604482015260640161074b565b506014015190565b606061195d613144836137f4565b6060808251600114801561317157506080835f815181106131675761316761489a565b016020015160f81c105b1561317d57508161195d565b61278161318c84516080613914565b84613ac4565b60605f61319e83613b41565b90506127816131af825160c0613914565b82613ac4565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff16610eb557604051631afcd79f60e31b815260040160405180910390fd5b6132066131b5565b6001600160a01b038116610ef357604051631e4fbdf760e01b81525f600482015260240161074b565b604080518082019091525f815260606020820152600182101561328a5760405162461bcd60e51b8152602060048201526013602482015272092dcecc2d8d2c840c8c2e8c240d8cadccee8d606b1b604482015260640161074b565b604080518082019091525f81526060602082015283835f8181106132b0576132b061489a565b919091013560f81c8252506132c88360018187614a9e565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060208201529392505050565b604080518082019091525f80825260208201528180602001905181019061195d9190614ac5565b604080518082019091525f8152606060208201528180602001905181019061195d9190614afd565b6040805160208101909152606081528180602001905181019061195d9190614b7a565b613381613dda565b6040805180820182525f8082526020808301829052835180850185528281528451808301909552828552908101939093529091905b845151811015613462575f855f015182815181106133d6576133d661489a565b60200260200101519050600160ff16815f015160ff16148015613404575060208401516001600160a01b0316155b801561340f57508351155b15613428576134218160200151613307565b9350613459565b805160ff166002148015613444575082516001600160a01b0316155b1561345957613456816020015161332e565b92505b506001016133b6565b5060408051808201909152918252602082015292915050565b5f5f60205f8451602086015f885af18061349a576040513d5f823e3d81fd5b50505f513d915081156134b15780600114156134be565b6001600160a01b0384163b155b15610b5a57604051635274afe760e01b81526001600160a01b038516600482015260240161074b565b80515f9081036134f857505f919050565b602082015180515f1a9060c0821015612fe657505f9392505050565b80515f90810361352557505f919050565b5f5f90505f6135378460200151613597565b84602001516135469190614530565b90505f845f0151856020015161355c9190614530565b90505b8082101561358e5761357082613616565b61357a9083614530565b91508261358681614ccc565b93505061355f565b50909392505050565b80515f90811a60808110156135ae57505f92915050565b60b88110806135c9575060c081108015906135c9575060f881105b156135d75750600192915050565b60c0811015613604576135ec600160b8614ce4565b6135f99060ff16826146a8565b612781906001614530565b6135ec600160f8614ce4565b50919050565b80515f908190811a608081101561363057600191506136b7565b60b8811015613656576136446080826146a8565b61364f906001614530565b91506136b7565b60c08110156136835760b78103600185019450806020036101000a855104600182018101935050506136b7565b60f88110156136975761364460c0826146a8565b60f78103600185019450806020036101000a855104600182018101935050505b5092915050565b5f5f5f6136ce8460200151613597565b90505f8185602001516136e19190614530565b90505f82865f01516136f391906146a8565b9196919550909350505050565b806001600160a01b03163b5f0361373557604051634c9c8ce360e01b81526001600160a01b038216600482015260240161074b565b5f516020614dff5f395f51905f5280546001600160a01b0319166001600160a01b0392909216919091179055565b60605f5f846001600160a01b03168460405161377f91906146bb565b5f60405180830381855af49150503d805f81146137b7576040519150601f19603f3d011682016040523d82523d5f602084013e6137bc565b606091505b50915091506137cc858383613cd9565b95945050505050565b3415610eb55760405163b398979f60e01b815260040160405180910390fd5b6040805160208082528183019092526060915f91906020820181803683375050506020810184905290505f5b60208110156138585781818151811061383b5761383b61489a565b01602001516001600160f81b0319165f0361385857600101613820565b5f6138648260206146a8565b6001600160401b0381111561387b5761387b613f0f565b6040519080825280601f01601f1916602001820160405280156138a5576020820181803683370190505b5090505f5b815181101561390b5783836138be81614ccc565b9450815181106138d0576138d061489a565b602001015160f81c60f81b8282815181106138ed576138ed61489a565b60200101906001600160f81b03191690815f1a9053506001016138aa565b50949350505050565b606080603884101561397c57604080516001808252818301909252906020820181803683370190505090506139498385614530565b601f1a60f81b815f815181106139615761396161489a565b60200101906001600160f81b03191690815f1a905350612781565b5f60015b61398a81876146fc565b156139b0578161399981614ccc565b92506139a99050610100826146d1565b9050613980565b6139bb826001614530565b6001600160401b038111156139d2576139d2613f0f565b6040519080825280601f01601f1916602001820160405280156139fc576020820181803683370190505b509250613a098583614530565b613a14906037614530565b601f1a60f81b835f81518110613a2c57613a2c61489a565b60200101906001600160f81b03191690815f1a905350600190505b818111613abb57610100613a5b82846146a8565b613a6790610100614de0565b613a7190886146fc565b613a7b9190614deb565b601f1a60f81b838281518110613a9357613a9361489a565b60200101906001600160f81b03191690815f1a90535080613ab381614ccc565b915050613a47565b50509392505050565b6060806040519050835180825260208201818101602087015b81831015613af5578051835260209283019201613add565b50855184518101855292509050808201602086015b81831015613b22578051835260209283019201613b0a565b508651929092011591909101601f01601f191660405250905092915050565b606081515f03613b6057604080515f80825260208201909252906136b7565b5f805b8351811015613c1c575f848281518110613b7f57613b7f61489a565b60200260200101515111613bec5760405162461bcd60e51b815260206004820152602e60248201527f416e206974656d20696e20746865206c69737420746f20626520524c5020656e60448201526d31b7b232b21034b990373ab6361760911b606482015260840161074b565b838181518110613bfe57613bfe61489a565b60200260200101515182613c129190614530565b9150600101613b63565b5f826001600160401b03811115613c3557613c35613f0f565b6040519080825280601f01601f191660200182016040528015613c5f576020820181803683370190505b505f92509050602081015b855183101561390b575f868481518110613c8657613c8661489a565b602002602001015190505f602082019050613ca383828451613d35565b878581518110613cb557613cb561489a565b60200260200101515183613cc99190614530565b6001909501949250613c6a915050565b606082613cee57613ce982613db1565b612781565b8151158015613d0557506001600160a01b0384163b155b15613d2e57604051639996b31560e01b81526001600160a01b038516600482015260240161074b565b5080612781565b8282825b60208110613d715781518352613d50602084614530565b9250613d5d602083614530565b9150613d6a6020826146a8565b9050613d39565b8015613da9575f6001613d858360206146a8565b613d9190610100614de0565b613d9b91906146a8565b835185518216911916178452505b505050505050565b805115613dc15780518082602001fd5b60405163d6bda27560e01b815260040160405180910390fd5b604080516080810182525f91810182815260608201929092529081908152602001613e2060405180604001604052805f6001600160a01b03168152602001606081525090565b905290565b5080545f8255600202905f5260205f2090810190610a0c91905b80821115613e635780546001600160a01b03191681555f6001820155600201613e3f565b5090565b5f6101c08284031215613610575f5ffd5b5f60208284031215613e88575f5ffd5b81356001600160401b03811115613e9d575f5ffd5b612faa84828501613e67565b5f5f5f5f60808587031215613ebc575f5ffd5b84356001600160401b03811115613ed1575f5ffd5b613edd87828801613e67565b97602087013597506040870135966060013595509350505050565b5f60208284031215613f08575f5ffd5b5035919050565b634e487b7160e01b5f52604160045260245ffd5b604080519081016001600160401b0381118282101715613f4557613f45613f0f565b60405290565b604051602081016001600160401b0381118282101715613f4557613f45613f0f565b604051601f8201601f191681016001600160401b0381118282101715613f9557613f95613f0f565b604052919050565b5f6001600160401b03821115613fb557613fb5613f0f565b50601f01601f191660200190565b5f82601f830112613fd2575f5ffd5b8135613fe5613fe082613f9d565b613f6d565b818152846020838601011115613ff9575f5ffd5b816020850160208301375f918101602001919091529392505050565b5f5f83601f840112614025575f5ffd5b5081356001600160401b0381111561403b575f5ffd5b6020830191508360208260051b8501011115614055575f5ffd5b9250929050565b5f5f5f5f5f5f5f60a0888a031215614072575f5ffd5b8735965060208801356001600160401b0381111561408e575f5ffd5b8801601f81018a1361409e575f5ffd5b80356001600160401b038111156140b3575f5ffd5b8a60208284010111156140c4575f5ffd5b602091909101965094506040880135935060608801356001600160401b038111156140ed575f5ffd5b6140f98a828b01613fc3565b93505060808801356001600160401b03811115614114575f5ffd5b6141208a828b01614015565b989b979a50959850939692959293505050565b6001600160a01b0381168114610a0c575f5ffd5b803561415281614133565b919050565b5f60208284031215614167575f5ffd5b813561278181614133565b5f5f60408385031215614183575f5ffd5b823561418e81614133565b915060208301356001600160401b038111156141a8575f5ffd5b6141b485828601613fc3565b9150509250929050565b8015158114610a0c575f5ffd5b8035614152816141be565b5f5f604083850312156141e7575f5ffd5b82356141f281614133565b91506020830135614202816141be565b809150509250929050565b5f5f6040838503121561421e575f5ffd5b50508035926020909101359150565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f612781602083018461422d565b5f5f5f5f5f5f60c08789031215614282575f5ffd5b8635955060208701356001600160401b0381111561429e575f5ffd5b6142aa89828a01613fc3565b955050604087013593506060870135925060808701356001600160401b038111156142d3575f5ffd5b6142df89828a01613fc3565b9699959850939692959460a09093013593505050565b5f5f5f5f60808587031215614308575f5ffd5b843561431381614133565b9350602085013561432381614133565b9250604085013561433381614133565b9396929550929360600135925050565b5f5f60408385031215614354575f5ffd5b8235915060208301356001600160401b038111156141a8575f5ffd5b5f5f8335601e19843603018112614385575f5ffd5b83016020810192503590506001600160401b038111156143a3575f5ffd5b803603821315614055575f5ffd5b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b803582525f6143ea60208301614147565b6001600160a01b0316602084015261440460408301614147565b6001600160a01b0316604084015261441e60608301614147565b6001600160a01b031660608401526080828101359084015260a0808301359084015260c0808301359084015261445660e083016141cb565b151560e084015261010082810135908401526101208083013590840152614481610140830183614370565b6101c06101408601526144996101c0860182846143b1565b9150506144aa610160840184614370565b8583036101608701526144be8382846143b1565b925050506144cf6101808401614147565b6001600160a01b03166101808501526144ec6101a0840184614370565b8583036101a08701526145008382846143b1565b9695505050505050565b602081525f61278160208301846143d9565b634e487b7160e01b5f52601160045260245ffd5b8082018082111561195d5761195d61451c565b828152604060208201525f612faa60408301846143d9565b87815260a060208201525f61457460a08301888a6143b1565b866040840152828103606084015261458c818761422d565b83810360808501528481529050602080820190600586901b830101865f5b878110156145e857848303601f190184526145c5828a614370565b6145d08582846143b1565b602096870196909550939093019250506001016145aa565b50909c9b505050505050505050505050565b600181811c9082168061460e57607f821691505b60208210810361361057634e487b7160e01b5f52602260045260245ffd5b5f5f8354614639816145fa565b600182168015614650576001811461466557612f5c565b60ff1983168652811515820286019350612f5c565b865f5260205f205f5b8381101561468a5781548882015260019091019060200161466e565b50505093909301949350505050565b818382375f9101908152919050565b8181038181111561195d5761195d61451c565b5f82518060208501845e5f920191825250919050565b808202811582820484141761195d5761195d61451c565b634e487b7160e01b5f52601260045260245ffd5b5f8261470a5761470a6146e8565b500490565b604081525f61472160408301856143d9565b90508260208301529392505050565b5f5f8335601e19843603018112614745575f5ffd5b8301803591506001600160401b0382111561475e575f5ffd5b602001915036819003821315614055575f5ffd5b838152606060208201525f61478a606083018561422d565b8281036040840152614500818561422d565b601f82111561178d57805f5260205f20601f840160051c810160208510156147c15750805b601f840160051c820191505b81811015611dd2575f81556001016147cd565b81516001600160401b038111156147f9576147f9613f0f565b61480d8161480784546145fa565b8461479c565b6020601f82116001811461483f575f83156148285750848201515b5f19600385901b1c1916600184901b178455611dd2565b5f84815260208120601f198516915b8281101561486e578785015182556020948501946001909201910161484e565b508482101561488b57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b634e487b7160e01b5f52603260045260245ffd5b5f602082840312156148be575f5ffd5b8135612781816141be565b60e081525f6148db60e08301876143d9565b855460ff90811615156020850152600187015460408501526002870154606085015260038701541615156080840152905060a082019390935260c0015292915050565b828152815460ff9081161515602083015260018301546040830152600283015460608301526003830154161515608082015260a08101612781565b5f60208284031215614969575f5ffd5b5051919050565b60c081525f61498260c08301866143d9565b905083511515602083015260208401516040830152604084015160608301526060840151151560808301528260a0830152949350505050565b5f602082840312156149cb575f5ffd5b8151612781816141be565b5f82601f8301126149e5575f5ffd5b81516149f3613fe082613f9d565b818152846020838601011115614a07575f5ffd5b8160208501602083015e5f918101602001919091529392505050565b5f5f60408385031215614a34575f5ffd5b825160208401519092506001600160401b03811115614a51575f5ffd5b6141b4858286016149d6565b6001600160a01b03841681526080602082018190525f90614a809083018561422d565b6040830193909352508082036060909101525f815260200192915050565b5f5f85851115614aac575f5ffd5b83861115614ab8575f5ffd5b5050820193919092039150565b5f6040828403128015614ad6575f5ffd5b50614adf613f23565b825181526020830151614af181614133565b60208201529392505050565b5f60208284031215614b0d575f5ffd5b81516001600160401b03811115614b22575f5ffd5b820160408185031215614b33575f5ffd5b614b3b613f23565b8151614b4681614133565b815260208201516001600160401b03811115614b60575f5ffd5b614b6c868285016149d6565b602083015250949350505050565b5f60208284031215614b8a575f5ffd5b81516001600160401b03811115614b9f575f5ffd5b820160208185031215614bb0575f5ffd5b614bb8613f4b565b81516001600160401b03811115614bcd575f5ffd5b80830192505084601f830112614be1575f5ffd5b81516001600160401b03811115614bfa57614bfa613f0f565b8060051b614c0a60208201613f6d565b91825260208185018101929081019088841115614c25575f5ffd5b6020860192505b83831015614cbe5782516001600160401b03811115614c49575f5ffd5b86016040818b03601f19011215614c5e575f5ffd5b614c66613f23565b602082015160ff81168114614c79575f5ffd5b815260408201516001600160401b03811115614c93575f5ffd5b614ca28c6020838601016149d6565b6020830152508084525050602082019150602083019250614c2c565b845250919695505050505050565b5f60018201614cdd57614cdd61451c565b5060010190565b60ff828116828216039081111561195d5761195d61451c565b6001815b6001841115614d3857808504811115614d1c57614d1c61451c565b6001841615614d2a57908102905b60019390931c928002614d01565b935093915050565b5f82614d4e5750600161195d565b81614d5a57505f61195d565b8160018114614d705760028114614d7a57614d96565b600191505061195d565b60ff841115614d8b57614d8b61451c565b50506001821b61195d565b5060208310610133831016604e8410600b8410161715614db9575081810a61195d565b614dc55f198484614cfd565b805f1904821115614dd857614dd861451c565b029392505050565b5f6127818383614d40565b5f82614df957614df96146e8565b50069056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00a2646970667358221220a27cbc0408f91e4fc6e91630d32a3e0ac92fd2bdc83f3071ab186e972a39cef364736f6c634300081c0033
Deployed Bytecode
0x6080604052600436106101d3575f3560e01c80638da5cb5b116100fd578063cf756fdf11610092578063e5795fd611610062578063e5795fd614610620578063ea6ced191461063f578063f2fde38b1461065e578063fd19016c1461067d575f5ffd5b8063cf756fdf146105c5578063d3da3330146105e4578063d971729f146105f9578063e30c39781461060c575f5ffd5b8063ad3cb1cc116100cd578063ad3cb1cc14610538578063c5c0369914610575578063ca25d31914610593578063cd01a9b0146105b2575f5ffd5b80638da5cb5b146104dd57806394217ad1146104f15780639a198d6114610510578063aaf10f4214610524575f5ffd5b80634f1ef28611610173578063715018a611610143578063715018a61461041f57806372f63f091461043357806379ba50971461048b57806388df70361461049f575f5ffd5b80634f1ef2861461036257806352d1902d14610375578063552800ac146103975780635ff8a66b146103b6575f5ffd5b806336cbe9e5116101ae57806336cbe9e51461023657806338e42f54146102be5780634b2b20e7146103055780634d88df2b14610324575f5ffd5b8063016f02e3146101de57806331f7d964146101f35780633468af4614610223575f5ffd5b366101da57005b5f5ffd5b6101f16101ec366004613e78565b61069c565b005b3480156101fe575f5ffd5b506102065f81565b6040516001600160a01b0390911681526020015b60405180910390f35b6101f1610231366004613ea9565b610a0f565b348015610241575f5ffd5b5061028a610250366004613ef8565b60056020525f90815260409020805460018201546002830154600384015460049094015492936001600160a01b0392831693929091169185565b604080519586526001600160a01b03948516602087015292909316918401919091526060830152608082015260a00161021a565b3480156102c9575f5ffd5b506102f06102d8366004613ef8565b60086020525f90815260409020805460019091015482565b6040805192835260208301919091520161021a565b348015610310575f5ffd5b506101f161031f36600461405c565b610b60565b34801561032f575f5ffd5b5061035261033e366004614157565b60076020525f908152604090205460ff1681565b604051901515815260200161021a565b6101f1610370366004614172565b610e38565b348015610380575f5ffd5b50610389610e57565b60405190815260200161021a565b3480156103a2575f5ffd5b506101f16103b13660046141d6565b610e72565b3480156103c1575f5ffd5b506103fb6103d0366004613ef8565b60046020525f9081526040902080546001820154600283015460039093015460ff9283169391921684565b6040805194151585526020850193909352918301521515606082015260800161021a565b34801561042a575f5ffd5b506101f1610ea4565b34801561043e575f5ffd5b5061046e61044d366004613ef8565b600a6020525f9081526040902080546001909101546001600160a01b031682565b604080519283526001600160a01b0390911660208301520161021a565b348015610496575f5ffd5b506101f1610eb7565b3480156104aa575f5ffd5b506104be6104b936600461420d565b610efc565b604080516001600160a01b03909316835260208301919091520161021a565b3480156104e8575f5ffd5b50610206610f3e565b3480156104fc575f5ffd5b50600154610206906001600160a01b031681565b34801561051b575f5ffd5b506101f1610f72565b34801561052f575f5ffd5b5061020661105b565b348015610543575f5ffd5b50610568604051806040016040528060058152602001640352e302e360dc1b81525081565b60405161021a919061425b565b348015610580575f5ffd5b505f54610206906001600160a01b031681565b34801561059e575f5ffd5b506101f16105ad366004613e78565b61107f565b6101f16105c036600461426d565b611402565b3480156105d0575f5ffd5b506101f16105df3660046142f5565b611565565b3480156105ef575f5ffd5b5061038960035481565b6101f1610607366004613ea9565b6116bd565b348015610617575f5ffd5b50610206611746565b34801561062b575f5ffd5b506101f161063a366004614343565b61176e565b34801561064a575f5ffd5b50610568610659366004613ef8565b611792565b348015610669575f5ffd5b506101f1610678366004614157565b611829565b348015610688575f5ffd5b50600254610206906001600160a01b031681565b6106a46118ae565b5f816040516020016106b6919061450a565b6040516020818303038152906040528051906020012090505f6106d8836118e5565b6020810151519091506001600160a01b03161561083e57336107006040850160208601614157565b6001600160a01b0316146107545760405162461bcd60e51b815260206004820152601660248201527521b932b0ba37b91036bab9ba1031329039b2b73232b960511b60448201526064015b60405180910390fd5b5f6107656060850160408601614157565b6001600160a01b0316036107d95760405162461bcd60e51b815260206004820152603560248201527f4e617469766520746f6b656e2063616e6e6f74206265207573656420617320696044820152746e70757420746f6b656e207769746820686f6f6b7360581b606482015260840161074b565b6020810151516040516307e7152560e41b81526001600160a01b0390911690637e7152509061080c90869060040161450a565b5f604051808303815f87803b158015610823575f5ffd5b505af1158015610835573d5f5f3e3d5ffd5b50505050610869565b8051516108676108546060860160408701614157565b610862836080880135614530565b611963565b505b5f828152600460209081526040918290208251608081018452815460ff9081161515808352600184015494830194909452600283015494820194909452600390910154909216151560608301526108e6575060408051608080820183526001825285013560208201525f918101829052606081019190915261092d565b80606001511561091457610909836109046060870160408801614157565b6119c6565b5f606082015261092d565b6040516302b000c160e21b815260040160405180910390fd5b7f29fecd55cf4a8b6d0aaf6870fbab480f04c3caab050a1af7654278af363cd96f838560405161095e929190614543565b60405180910390a180602001515f036109a6575f838152600460205260408120805460ff199081168255600182018390556002820192909255600301805490911690556109f3565b5f838152600460209081526040918290208351815490151560ff19918216178255918401516001820155918301516002830155606083015160039092018054921515929091169190911790555b505050610a0c60015f516020614e1f5f395f51905f5255565b50565b610a176118ae565b5f84604051602001610a29919061450a565b60408051601f1981840301815291815281516020928301205f818152600490935290822090925090610a5a876118e5565b60200151516001600160a01b031614610ac45760405162461bcd60e51b815260206004820152602660248201527f486f6f6b7320617265206e6f7420616c6c6f77656420746f206265207072652d604482015265199a5b1b195960d21b606482015260840161074b565b805460ff16610b3557604080516080808201835260018083529089013560208084019182525f8486018181526060860185815289835260049093529590209351845490151560ff19918216178555915192840192909255925160028301555160039091018054911515919092161790555b610b428683878787611a54565b5050610b5a60015f516020614e1f5f395f51905f5255565b50505050565b610b686118ae565b60025460405163372ff73f60e21b81526001600160a01b039091169063dcbfdcfc90610ba4908a908a908a908a908a908a908a9060040161455b565b5f604051808303815f87803b158015610bbb575f5ffd5b505af1158015610bcd573d5f5f3e3d5ffd5b5050505f88815260066020526040908190209051610beb925061462c565b60405180910390208686604051610c03929190614699565b604051809103902014610c14575f5ffd5b5f610c1e84611dd9565b80515f908152600560208181526040808420815160a081018352815481526001808301546001600160a01b0390811683870152600280850154909116838601526003808501546060850190815260049586015460808601528a518a5297875285892089815592830180546001600160a01b0319908116909155918301805490921690915581018790559091018590558051808652600890935290842092518354959650909491939091839190610cd59084906146a8565b909155505060808301516001820180545f90610cf29084906146a8565b909155505080545f03610d18575f82815260086020526040812081815560010155610d33565b5f828152600860205260409020815481556001808301549101555b8360200151610db85783516040805191825284516020808401919091528501516001600160a01b0390811683830152858201511660608084019190915285015160808084019190915285015160a0830152517f903cf0a603920e4f3e45542f8960563511f94eba7d94077a61067e409cd3e1e19181900360c00190a150505050610e19565b5f828152600460209081526040808320606087015160808801518884015189860151600a875296859020855180870190965280548652600101546001600160a01b0316958501959095529194610e1394889487949290611e7d565b50505050505b610e2f60015f516020614e1f5f395f51905f5255565b50505050505050565b610e406120c1565b610e4982612165565b610e53828261216d565b5050565b5f610e60612229565b505f516020614dff5f395f51905f5290565b610e7a612272565b6001600160a01b03919091165f908152600760205260409020805460ff1916911515919091179055565b610eac612272565b610eb55f6122a4565b565b3380610ec1611746565b6001600160a01b031614610ef35760405163118cdaa760e01b81526001600160a01b038216600482015260240161074b565b610a0c816122a4565b6009602052815f5260405f208181548110610f15575f80fd5b5f918252602090912060029091020180546001909101546001600160a01b039091169250905082565b5f807f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c1993005b546001600160a01b031692915050565b604051609e60248201525f9073dc2b0d2dd2b7759d97d50db4eabdc369731108309060440160408051601f198184030181529181526020820180516001600160e01b03166307983f4560e21b17905251610fcc91906146bb565b5f604051808303815f865af19150503d805f8114611005576040519150601f19603f3d011682016040523d82523d5f602084013e61100a565b606091505b5050905080610a0c5760405162461bcd60e51b815260206004820152601860248201527f4665654d20726567697374726174696f6e206661696c65640000000000000000604482015260640161074b565b5f61107a5f516020614dff5f395f51905f52546001600160a01b031690565b905090565b6110876118ae565b5f81604051602001611099919061450a565b60408051601f1981840301815291815281516020928301205f818152600484528281206008909452918220600184015491945091036110eb576040516361ae648360e01b815260040160405180910390fd5b60018101541561110e5760405163bd10ceab60e01b815260040160405180910390fd5b61111e6040850160208601614157565b6001600160a01b0316336001600160a01b03161415801561114f575060c0840135158061114f57508360c001354211155b801561119d575060408051608081018252835460ff908116151582526001850154602083015260028501549282019290925260038401549091161515606082015261119b9085906122dc565b155b156111ba576040516282b42960e81b815260040160405180910390fd5b60018201541561137f575f6111ce856118e5565b90505f836001015486608001356111e591906146a8565b8251602001519091505f906001600160a01b031615801590611208575082515115155b1561122e578251516080880135906112219084906146d1565b61122b91906146fc565b90505b8015611253576112536112476060890160408a01614157565b845160200151836123f5565b8251515f906112639083906146a8565b90505f8187600101546112769190614530565b5f898152600a602090815260408220918255600190910180546001600160a01b0319169055860151519091506001600160a01b03161561131757602085015151604051639645380760e01b81526001600160a01b03909116906396453807906112e5908c90859060040161470f565b5f604051808303815f87803b1580156112fc575f5ffd5b505af115801561130e573d5f5f3e3d5ffd5b50505050611379565b61137961132a60608b0160408c01614157565b6101008b013561133e6101408d018d614730565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152508792506124a7915050565b50505050505b5f83815260046020526040808220805460ff1990811682556001820184905560028201939093556003018054909216909155517fc08eb64db16a39d2848960af04e3f16fb404d9d436a9f0e9d7d0d4854715c9dc906113e19085815260200190565b60405180910390a1505050610a0c60015f516020614e1f5f395f51905f5255565b5f818152600660205260408120805461141a906145fa565b80601f0160208091040260200160405190810160405280929190818152602001828054611446906145fa565b80156114915780601f1061146857610100808354040283529160200191611491565b820191905f5260205f20905b81548152906001019060200180831161147457829003601f168201915b505050505090505f6040518060c00160405280868152602001896040516020016114bd91815260200190565b60408051601f1981840301815291905281526020016114db33612611565b815260208101869052604081018990526060018790526002549091506001600160a01b0316636ea9cec9848461151085612647565b6040518463ffffffff1660e01b815260040161152e93929190614772565b5f604051808303815f87803b158015611545575f5ffd5b505af1158015611557573d5f5f3e3d5ffd5b505050505050505050505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff1615906001600160401b03165f811580156115a95750825b90505f826001600160401b031660011480156115c45750303b155b9050811580156115d2575080155b156115f05760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561161a57845460ff60401b1916600160401b1785555b61162333612788565b61162b612799565b5f80546001600160a01b03808c166001600160a01b031992831617909255600180548b841690831617905560028054928a1692909116919091179055600386905583156116b257845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050505050565b6116c56118ae565b5f846040516020016116d7919061450a565b60408051601f1981840301815291815281516020928301205f8181526004909352912080549192509060ff16611720576040516361ae648360e01b815260040160405180910390fd5b600381015460ff1615610b35576040516361ae648360e01b815260040160405180910390fd5b5f807f237e158222e3e6968b72b9db0d8043aacf074ad9f650f0d1606b4d82ee432c00610f62565b611776612272565b5f82815260066020526040902061178d82826147e0565b505050565b60066020525f9081526040902080546117aa906145fa565b80601f01602080910402602001604051908101604052809291908181526020018280546117d6906145fa565b80156118215780601f106117f857610100808354040283529160200191611821565b820191905f5260205f20905b81548152906001019060200180831161180457829003601f168201915b505050505081565b611831612272565b7f237e158222e3e6968b72b9db0d8043aacf074ad9f650f0d1606b4d82ee432c0080546001600160a01b0319166001600160a01b0383169081178255611875610f3e565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a35050565b5f516020614e1f5f395f51905f528054600119016118df57604051633ee5aeb560e01b815260040160405180910390fd5b60029055565b6118ed613dda565b6118fb6101a0830183614730565b90505f03611947575050604080516080810182525f8183018181526060830182905282528251808401845281815283516020818101909552918252808401919091529181019190915290565b61195d6119586101a0840184614730565b6127a1565b92915050565b805f036119835760405163162908e360e11b815260040160405180910390fd5b6001600160a01b0382166119b157803414610e535760405163162908e360e11b815260040160405180910390fd5b610e536001600160a01b03831633308461291d565b5f828152600960205260408120905b8154811015611a3d575f8282815481106119f1576119f161489a565b5f9182526020918290206040805180820190915260029092020180546001600160a01b0316808352600190910154928201839052909250611a34918691906123f5565b506001016119d5565b505f83815260096020526040812061178d91613e25565b5f848152600460209081526040808320600890925282209091611a76886118e5565b51835490915060ff16611a9c576040516361ae648360e01b815260040160405180910390fd5b815460018401545f91611aae916146a8565b905080871115611ad15760405163162908e360e11b815260040160405180910390fd5b8087108015611aee5750611aec6101008a0160e08b016148ae565b155b15611b0c576040516323bc005f60e21b815260040160405180910390fd5b5f611b1f6101a08b016101808c01614157565b6001600160a01b031614158015611b50575033611b446101a08b016101808c01614157565b6001600160a01b031614155b15611b6e5760405163af24067760e01b815260040160405180910390fd5b5f60808a0135611b8260a08c01358a6146d1565b611b8c91906146fc565b905080871015611baf5760405163162908e360e11b815260040160405180910390fd5b5f611bb98b6118e5565b90508615611bda57611bcf8b8b8b8b8b86612984565b505050505050611dd2565b611bf3611bed60808d0160608e01614157565b89611963565b611c55611c0660808d0160608e01614157565b6101208d0135611c1a6101608f018f614730565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152508e92506124a7915050565b6020810151516001600160a01b031615611da857600386015460ff1615611cb55760405162461bcd60e51b815260206004820152601460248201527343616e6e6f742070726566696c6c20686f6f6b7360601b604482015260640161074b565b60408051608081018252875460ff90811615158252600189015460208301526002890154928201929092526003880154909116151560608201525f90611cfd908d908c612db4565b6020830151519091506001600160a01b031663d4ef80518d89611d20858f614530565b8d6040518563ffffffff1660e01b8152600401611d4094939291906148c9565b5f604051808303815f87803b158015611d57575f5ffd5b505af1158015611d69573d5f5f3e3d5ffd5b505050602083015151611da6915030611d82848e614530565b8f6040016020810190611d959190614157565b6001600160a01b031692919061291d565b505b611dcb8a878b8b8f6040016020810190611dc29190614157565b86513390611e7d565b5050505050505b5050505050565b6040805180820182525f8082526020808301829052835180850185528281528101829052835180850190945284518452848101908401529091611e1b90612e62565b90506040518060400160405280611e4a835f81518110611e3d57611e3d61489a565b6020026020010151612f67565b8152602001611e7283600181518110611e6557611e6561489a565b6020026020010151612fb2565b151590529392505050565b83866002015f828254611e909190614530565b9250508190555084866001015f828254611eaa91906146a8565b90915550506040517f179edcc2ff551e1336d178824736b025cc5df1a59d05fbcb69ae2de8c06433da90611ee1908990899061491e565b60405180910390a160018601545f908103611f1b575080515f888152600a6020526040812090815560010180546001600160a01b03191690555b6001870154158015611f325750600387015460ff16155b15611f6c575f888152600460205260408120805460ff19908116825560018201839055600282019290925560030180549091169055611fba565b5f8881526004602052604090208754815460ff918216151560ff199182161783556001808b0154908401556002808b0154908401556003808b01549301805493909216151592169190911790555b600387015460ff1615612097575f88815260096020908152604080832081518083019092526001600160a01b0387811683528284018b8152825460018082018555938752949095209251600290940290920180546001600160a01b0319169390921692909217815591519101558015612092575f8881526009602090815260408083208151808301909252858301516001600160a01b039081168352828401868152825460018082018555938752949095209251600290940290920180546001600160a01b0319169390921692909217815591519101555b6120b7565b6120a28484886123f5565b80156120b7576120b7848360200151836123f5565b5050505050505050565b306001600160a01b037f0000000000000000000000005057297e77a73c655106bc18e441a9595f3219f816148061214757507f0000000000000000000000005057297e77a73c655106bc18e441a9595f3219f86001600160a01b031661213b5f516020614dff5f395f51905f52546001600160a01b031690565b6001600160a01b031614155b15610eb55760405163703e46dd60e11b815260040160405180910390fd5b610a0c612272565b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156121c7575060408051601f3d908101601f191682019092526121c491810190614959565b60015b6121ef57604051634c9c8ce360e01b81526001600160a01b038316600482015260240161074b565b5f516020614dff5f395f51905f52811461221f57604051632a87526960e21b81526004810182905260240161074b565b61178d8383612ff0565b306001600160a01b037f0000000000000000000000005057297e77a73c655106bc18e441a9595f3219f81614610eb55760405163703e46dd60e11b815260040160405180910390fd5b3361227b610f3e565b6001600160a01b031614610eb55760405163118cdaa760e01b815233600482015260240161074b565b7f237e158222e3e6968b72b9db0d8043aacf074ad9f650f0d1606b4d82ee432c0080546001600160a01b0319168155610e5382613045565b5f5f6122e7846118e5565b602080820151519192506123019060408701908701614157565b6001600160a01b0316336001600160a01b031614158015612332575060c0850135158061233257508460c001354211155b156123eb576001600160a01b038116156123eb575f61236085866020015188612db49092919063ffffffff16565b856020015161236f9190614530565b6040516354874b1560e11b81529091506001600160a01b0383169063a90e962a906123a290899089908690600401614970565b602060405180830381865afa1580156123bd573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906123e191906149bb565b935050505061195d565b505f949350505050565b805f036124155760405163162908e360e11b815260040160405180910390fd5b6001600160a01b038316612493575f826001600160a01b0316826040515f6040518083038185875af1925050503d805f811461246c576040519150601f19603f3d011682016040523d82523d5f602084013e612471565b606091505b5050905080610b5a576040516312171d8360e31b815260040160405180910390fd5b61178d6001600160a01b03841683836130b5565b805f036124c75760405163162908e360e11b815260040160405180910390fd5b60035483036124e8576124e3846124dd846130e6565b836123f5565b610b5a565b600154604051634586e5a760e11b81526001600160a01b0386811660048301525f921690638b0dcb4e906024015f60405180830381865afa15801561252f573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526125569190810190614a23565b5090508084146125b45760405162461bcd60e51b8152602060048201526024808201527f496e76616c69642064657374696e6174696f6e2061646472657373206f72207460448201526337b5b2b760e11b606482015260840161074b565b60015460405163c6b4180b60e01b81526001600160a01b039091169063c6b4180b906125e890889087908790600401614a5d565b5f604051808303815f87803b1580156125ff575f5ffd5b505af11580156116b2573d5f5f3e3d5ffd5b604051606082811b6bffffffffffffffffffffffff19166020830152906034016040516020818303038152906040529050919050565b60408051600680825260e082019092526060915f9190816020015b6060815260200190600190039081612662575050835190915061268490613136565b815f815181106126965761269661489a565b60200260200101819052506126ae8360200151613144565b816001815181106126c1576126c161489a565b60200260200101819052506126d98360400151613144565b816002815181106126ec576126ec61489a565b60200260200101819052506127048360600151613144565b816003815181106127175761271761489a565b602002602001018190525061272f8360800151613144565b816004815181106127425761274261489a565b602002602001018190525061275a8360a00151613136565b8160058151811061276d5761276d61489a565b602002602001018190525061278181613192565b9392505050565b6127906131b5565b610a0c816131fe565b610eb56131b5565b6127a9613dda565b5f8290036127f65750604080516080810182525f8183018181526060830182905282528251808401845281815283516020818101909552918252808401919091529181019190915261195d565b5f612801848461322f565b9050600160ff16815f015160ff160361285857604051806040016040528061282c8360200151613307565b81526040805180820182525f8082528251602081810190945290815281830152910152915061195d9050565b805160ff16600119016128ab57604051806040016040528060405180604001604052805f81526020015f6001600160a01b031681525081526020016128a0836020015161332e565b81525091505061195d565b805160ff166128d6575f6128c28260200151613356565b90506128cd81613379565b9250505061195d565b5050604080516080810182525f8183018181526060830182905282528251808401845281815283516020818101909552918252808401919091529181019190915292915050565b6040516001600160a01b038481166024830152838116604483015260648201839052610b5a9186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b03838183161783525050505061347b565b335f9081526007602052604090205460ff166129b2576040516282b42960e81b815260040160405180910390fd5b6020810151516001600160a01b0316156129df5760405163135d8d3b60e21b815260040160405180910390fd5b6101208601355f90815260066020526040812080546129fd906145fa565b80601f0160208091040260200160405190810160405280929190818152602001828054612a29906145fa565b8015612a745780601f10612a4b57610100808354040283529160200191612a74565b820191905f5260205f20905b815481529060010190602001808311612a5757829003601f168201915b5050505050905080515f03612a9c57604051630e16ee5960e21b815260040160405180910390fd5b5f8381526005602052604090206004015415612acb57604051638b7071a960e01b815260040160405180910390fd5b6001545f9081906001600160a01b0316638b0dcb4e612af060808c0160608d01614157565b6040516001600160e01b031960e084901b1681526001600160a01b0390911660048201526024015f60405180830381865afa158015612b31573d5f5f3e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052612b589190810190614a23565b915091508861012001358214612b80576040516231010160e51b815260040160405180910390fd5b5f888152600860205260408120805490918991839190612ba1908490614530565b9250508190555086816001015f828254612bbb9190614530565b90915550505f89815260086020908152604080832084548155600180860154918101919091558851600a84528285208151815590840151910180546001600160a01b0319166001600160a01b03909216919091179055805160c08101825289815281518084018e905290928301910160408051601f198184030181529190528152602001612c4833612611565b8152602001612c5b6101608e018e614730565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250505090825250602080820186905260409182018b9052815160a0810183528d8152339181019190915291925081810190612ccb9060608f01908f01614157565b6001600160a01b03908116825260208083018d905260409283018c90525f8b81526005825283902084518155908401516001820180549184166001600160a01b031992831617905592840151600280830180549285169290951691909117909355606084015160038201556080909301516004909301929092555416636ea9cec96101208d013587612d5c85612647565b6040518463ffffffff1660e01b8152600401612d7a93929190614772565b5f604051808303815f87803b158015612d91575f5ffd5b505af1158015612da3573d5f5f3e3d5ffd5b505050505050505050505050505050565b5f5f612dbf856118e5565b5180519091501580612ddc575060208101516001600160a01b0316155b15612dea575f915050612781565b60208401516080860135905f90612e0190836146a8565b90505f612e0e8683614530565b90505f8383865f0151612e2191906146d1565b612e2b91906146fc565b90505f8483875f0151612e3e91906146d1565b612e4891906146fc565b9050612e5482826146a8565b9a9950505050505050505050565b6060612e6d826134e7565b612e75575f5ffd5b5f612e7f83613514565b90505f816001600160401b03811115612e9a57612e9a613f0f565b604051908082528060200260200182016040528015612ede57816020015b604080518082019091525f8082526020820152815260200190600190039081612eb85790505b5090505f612eef8560200151613597565b8560200151612efe9190614530565b90505f805b84811015612f5c57612f1483613616565b9150604051806040016040528083815260200184815250848281518110612f3d57612f3d61489a565b6020908102919091010152612f528284614530565b9250600101612f03565b509195945050505050565b80515f9015801590612f7b57508151602110155b612f83575f5ffd5b5f5f612f8e846136be565b815191935091506020821015612faa5760208290036101000a90045b949350505050565b80515f90600114612fc1575f5ffd5b602082015180515f1a90811580612fd85750608082145b15612fe657505f9392505050565b5060019392505050565b612ff982613700565b6040516001600160a01b038316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a280511561303d5761178d8282613763565b610e536137d5565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b6040516001600160a01b0383811660248301526044820183905261178d91859182169063a9059cbb90606401612952565b5f815160141461312e5760405162461bcd60e51b8152602060048201526013602482015272092dcecc2d8d2c840c8c2e8c240d8cadccee8d606b1b604482015260640161074b565b506014015190565b606061195d613144836137f4565b6060808251600114801561317157506080835f815181106131675761316761489a565b016020015160f81c105b1561317d57508161195d565b61278161318c84516080613914565b84613ac4565b60605f61319e83613b41565b90506127816131af825160c0613914565b82613ac4565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff16610eb557604051631afcd79f60e31b815260040160405180910390fd5b6132066131b5565b6001600160a01b038116610ef357604051631e4fbdf760e01b81525f600482015260240161074b565b604080518082019091525f815260606020820152600182101561328a5760405162461bcd60e51b8152602060048201526013602482015272092dcecc2d8d2c840c8c2e8c240d8cadccee8d606b1b604482015260640161074b565b604080518082019091525f81526060602082015283835f8181106132b0576132b061489a565b919091013560f81c8252506132c88360018187614a9e565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050505060208201529392505050565b604080518082019091525f80825260208201528180602001905181019061195d9190614ac5565b604080518082019091525f8152606060208201528180602001905181019061195d9190614afd565b6040805160208101909152606081528180602001905181019061195d9190614b7a565b613381613dda565b6040805180820182525f8082526020808301829052835180850185528281528451808301909552828552908101939093529091905b845151811015613462575f855f015182815181106133d6576133d661489a565b60200260200101519050600160ff16815f015160ff16148015613404575060208401516001600160a01b0316155b801561340f57508351155b15613428576134218160200151613307565b9350613459565b805160ff166002148015613444575082516001600160a01b0316155b1561345957613456816020015161332e565b92505b506001016133b6565b5060408051808201909152918252602082015292915050565b5f5f60205f8451602086015f885af18061349a576040513d5f823e3d81fd5b50505f513d915081156134b15780600114156134be565b6001600160a01b0384163b155b15610b5a57604051635274afe760e01b81526001600160a01b038516600482015260240161074b565b80515f9081036134f857505f919050565b602082015180515f1a9060c0821015612fe657505f9392505050565b80515f90810361352557505f919050565b5f5f90505f6135378460200151613597565b84602001516135469190614530565b90505f845f0151856020015161355c9190614530565b90505b8082101561358e5761357082613616565b61357a9083614530565b91508261358681614ccc565b93505061355f565b50909392505050565b80515f90811a60808110156135ae57505f92915050565b60b88110806135c9575060c081108015906135c9575060f881105b156135d75750600192915050565b60c0811015613604576135ec600160b8614ce4565b6135f99060ff16826146a8565b612781906001614530565b6135ec600160f8614ce4565b50919050565b80515f908190811a608081101561363057600191506136b7565b60b8811015613656576136446080826146a8565b61364f906001614530565b91506136b7565b60c08110156136835760b78103600185019450806020036101000a855104600182018101935050506136b7565b60f88110156136975761364460c0826146a8565b60f78103600185019450806020036101000a855104600182018101935050505b5092915050565b5f5f5f6136ce8460200151613597565b90505f8185602001516136e19190614530565b90505f82865f01516136f391906146a8565b9196919550909350505050565b806001600160a01b03163b5f0361373557604051634c9c8ce360e01b81526001600160a01b038216600482015260240161074b565b5f516020614dff5f395f51905f5280546001600160a01b0319166001600160a01b0392909216919091179055565b60605f5f846001600160a01b03168460405161377f91906146bb565b5f60405180830381855af49150503d805f81146137b7576040519150601f19603f3d011682016040523d82523d5f602084013e6137bc565b606091505b50915091506137cc858383613cd9565b95945050505050565b3415610eb55760405163b398979f60e01b815260040160405180910390fd5b6040805160208082528183019092526060915f91906020820181803683375050506020810184905290505f5b60208110156138585781818151811061383b5761383b61489a565b01602001516001600160f81b0319165f0361385857600101613820565b5f6138648260206146a8565b6001600160401b0381111561387b5761387b613f0f565b6040519080825280601f01601f1916602001820160405280156138a5576020820181803683370190505b5090505f5b815181101561390b5783836138be81614ccc565b9450815181106138d0576138d061489a565b602001015160f81c60f81b8282815181106138ed576138ed61489a565b60200101906001600160f81b03191690815f1a9053506001016138aa565b50949350505050565b606080603884101561397c57604080516001808252818301909252906020820181803683370190505090506139498385614530565b601f1a60f81b815f815181106139615761396161489a565b60200101906001600160f81b03191690815f1a905350612781565b5f60015b61398a81876146fc565b156139b0578161399981614ccc565b92506139a99050610100826146d1565b9050613980565b6139bb826001614530565b6001600160401b038111156139d2576139d2613f0f565b6040519080825280601f01601f1916602001820160405280156139fc576020820181803683370190505b509250613a098583614530565b613a14906037614530565b601f1a60f81b835f81518110613a2c57613a2c61489a565b60200101906001600160f81b03191690815f1a905350600190505b818111613abb57610100613a5b82846146a8565b613a6790610100614de0565b613a7190886146fc565b613a7b9190614deb565b601f1a60f81b838281518110613a9357613a9361489a565b60200101906001600160f81b03191690815f1a90535080613ab381614ccc565b915050613a47565b50509392505050565b6060806040519050835180825260208201818101602087015b81831015613af5578051835260209283019201613add565b50855184518101855292509050808201602086015b81831015613b22578051835260209283019201613b0a565b508651929092011591909101601f01601f191660405250905092915050565b606081515f03613b6057604080515f80825260208201909252906136b7565b5f805b8351811015613c1c575f848281518110613b7f57613b7f61489a565b60200260200101515111613bec5760405162461bcd60e51b815260206004820152602e60248201527f416e206974656d20696e20746865206c69737420746f20626520524c5020656e60448201526d31b7b232b21034b990373ab6361760911b606482015260840161074b565b838181518110613bfe57613bfe61489a565b60200260200101515182613c129190614530565b9150600101613b63565b5f826001600160401b03811115613c3557613c35613f0f565b6040519080825280601f01601f191660200182016040528015613c5f576020820181803683370190505b505f92509050602081015b855183101561390b575f868481518110613c8657613c8661489a565b602002602001015190505f602082019050613ca383828451613d35565b878581518110613cb557613cb561489a565b60200260200101515183613cc99190614530565b6001909501949250613c6a915050565b606082613cee57613ce982613db1565b612781565b8151158015613d0557506001600160a01b0384163b155b15613d2e57604051639996b31560e01b81526001600160a01b038516600482015260240161074b565b5080612781565b8282825b60208110613d715781518352613d50602084614530565b9250613d5d602083614530565b9150613d6a6020826146a8565b9050613d39565b8015613da9575f6001613d858360206146a8565b613d9190610100614de0565b613d9b91906146a8565b835185518216911916178452505b505050505050565b805115613dc15780518082602001fd5b60405163d6bda27560e01b815260040160405180910390fd5b604080516080810182525f91810182815260608201929092529081908152602001613e2060405180604001604052805f6001600160a01b03168152602001606081525090565b905290565b5080545f8255600202905f5260205f2090810190610a0c91905b80821115613e635780546001600160a01b03191681555f6001820155600201613e3f565b5090565b5f6101c08284031215613610575f5ffd5b5f60208284031215613e88575f5ffd5b81356001600160401b03811115613e9d575f5ffd5b612faa84828501613e67565b5f5f5f5f60808587031215613ebc575f5ffd5b84356001600160401b03811115613ed1575f5ffd5b613edd87828801613e67565b97602087013597506040870135966060013595509350505050565b5f60208284031215613f08575f5ffd5b5035919050565b634e487b7160e01b5f52604160045260245ffd5b604080519081016001600160401b0381118282101715613f4557613f45613f0f565b60405290565b604051602081016001600160401b0381118282101715613f4557613f45613f0f565b604051601f8201601f191681016001600160401b0381118282101715613f9557613f95613f0f565b604052919050565b5f6001600160401b03821115613fb557613fb5613f0f565b50601f01601f191660200190565b5f82601f830112613fd2575f5ffd5b8135613fe5613fe082613f9d565b613f6d565b818152846020838601011115613ff9575f5ffd5b816020850160208301375f918101602001919091529392505050565b5f5f83601f840112614025575f5ffd5b5081356001600160401b0381111561403b575f5ffd5b6020830191508360208260051b8501011115614055575f5ffd5b9250929050565b5f5f5f5f5f5f5f60a0888a031215614072575f5ffd5b8735965060208801356001600160401b0381111561408e575f5ffd5b8801601f81018a1361409e575f5ffd5b80356001600160401b038111156140b3575f5ffd5b8a60208284010111156140c4575f5ffd5b602091909101965094506040880135935060608801356001600160401b038111156140ed575f5ffd5b6140f98a828b01613fc3565b93505060808801356001600160401b03811115614114575f5ffd5b6141208a828b01614015565b989b979a50959850939692959293505050565b6001600160a01b0381168114610a0c575f5ffd5b803561415281614133565b919050565b5f60208284031215614167575f5ffd5b813561278181614133565b5f5f60408385031215614183575f5ffd5b823561418e81614133565b915060208301356001600160401b038111156141a8575f5ffd5b6141b485828601613fc3565b9150509250929050565b8015158114610a0c575f5ffd5b8035614152816141be565b5f5f604083850312156141e7575f5ffd5b82356141f281614133565b91506020830135614202816141be565b809150509250929050565b5f5f6040838503121561421e575f5ffd5b50508035926020909101359150565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f612781602083018461422d565b5f5f5f5f5f5f60c08789031215614282575f5ffd5b8635955060208701356001600160401b0381111561429e575f5ffd5b6142aa89828a01613fc3565b955050604087013593506060870135925060808701356001600160401b038111156142d3575f5ffd5b6142df89828a01613fc3565b9699959850939692959460a09093013593505050565b5f5f5f5f60808587031215614308575f5ffd5b843561431381614133565b9350602085013561432381614133565b9250604085013561433381614133565b9396929550929360600135925050565b5f5f60408385031215614354575f5ffd5b8235915060208301356001600160401b038111156141a8575f5ffd5b5f5f8335601e19843603018112614385575f5ffd5b83016020810192503590506001600160401b038111156143a3575f5ffd5b803603821315614055575f5ffd5b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b803582525f6143ea60208301614147565b6001600160a01b0316602084015261440460408301614147565b6001600160a01b0316604084015261441e60608301614147565b6001600160a01b031660608401526080828101359084015260a0808301359084015260c0808301359084015261445660e083016141cb565b151560e084015261010082810135908401526101208083013590840152614481610140830183614370565b6101c06101408601526144996101c0860182846143b1565b9150506144aa610160840184614370565b8583036101608701526144be8382846143b1565b925050506144cf6101808401614147565b6001600160a01b03166101808501526144ec6101a0840184614370565b8583036101a08701526145008382846143b1565b9695505050505050565b602081525f61278160208301846143d9565b634e487b7160e01b5f52601160045260245ffd5b8082018082111561195d5761195d61451c565b828152604060208201525f612faa60408301846143d9565b87815260a060208201525f61457460a08301888a6143b1565b866040840152828103606084015261458c818761422d565b83810360808501528481529050602080820190600586901b830101865f5b878110156145e857848303601f190184526145c5828a614370565b6145d08582846143b1565b602096870196909550939093019250506001016145aa565b50909c9b505050505050505050505050565b600181811c9082168061460e57607f821691505b60208210810361361057634e487b7160e01b5f52602260045260245ffd5b5f5f8354614639816145fa565b600182168015614650576001811461466557612f5c565b60ff1983168652811515820286019350612f5c565b865f5260205f205f5b8381101561468a5781548882015260019091019060200161466e565b50505093909301949350505050565b818382375f9101908152919050565b8181038181111561195d5761195d61451c565b5f82518060208501845e5f920191825250919050565b808202811582820484141761195d5761195d61451c565b634e487b7160e01b5f52601260045260245ffd5b5f8261470a5761470a6146e8565b500490565b604081525f61472160408301856143d9565b90508260208301529392505050565b5f5f8335601e19843603018112614745575f5ffd5b8301803591506001600160401b0382111561475e575f5ffd5b602001915036819003821315614055575f5ffd5b838152606060208201525f61478a606083018561422d565b8281036040840152614500818561422d565b601f82111561178d57805f5260205f20601f840160051c810160208510156147c15750805b601f840160051c820191505b81811015611dd2575f81556001016147cd565b81516001600160401b038111156147f9576147f9613f0f565b61480d8161480784546145fa565b8461479c565b6020601f82116001811461483f575f83156148285750848201515b5f19600385901b1c1916600184901b178455611dd2565b5f84815260208120601f198516915b8281101561486e578785015182556020948501946001909201910161484e565b508482101561488b57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b634e487b7160e01b5f52603260045260245ffd5b5f602082840312156148be575f5ffd5b8135612781816141be565b60e081525f6148db60e08301876143d9565b855460ff90811615156020850152600187015460408501526002870154606085015260038701541615156080840152905060a082019390935260c0015292915050565b828152815460ff9081161515602083015260018301546040830152600283015460608301526003830154161515608082015260a08101612781565b5f60208284031215614969575f5ffd5b5051919050565b60c081525f61498260c08301866143d9565b905083511515602083015260208401516040830152604084015160608301526060840151151560808301528260a0830152949350505050565b5f602082840312156149cb575f5ffd5b8151612781816141be565b5f82601f8301126149e5575f5ffd5b81516149f3613fe082613f9d565b818152846020838601011115614a07575f5ffd5b8160208501602083015e5f918101602001919091529392505050565b5f5f60408385031215614a34575f5ffd5b825160208401519092506001600160401b03811115614a51575f5ffd5b6141b4858286016149d6565b6001600160a01b03841681526080602082018190525f90614a809083018561422d565b6040830193909352508082036060909101525f815260200192915050565b5f5f85851115614aac575f5ffd5b83861115614ab8575f5ffd5b5050820193919092039150565b5f6040828403128015614ad6575f5ffd5b50614adf613f23565b825181526020830151614af181614133565b60208201529392505050565b5f60208284031215614b0d575f5ffd5b81516001600160401b03811115614b22575f5ffd5b820160408185031215614b33575f5ffd5b614b3b613f23565b8151614b4681614133565b815260208201516001600160401b03811115614b60575f5ffd5b614b6c868285016149d6565b602083015250949350505050565b5f60208284031215614b8a575f5ffd5b81516001600160401b03811115614b9f575f5ffd5b820160208185031215614bb0575f5ffd5b614bb8613f4b565b81516001600160401b03811115614bcd575f5ffd5b80830192505084601f830112614be1575f5ffd5b81516001600160401b03811115614bfa57614bfa613f0f565b8060051b614c0a60208201613f6d565b91825260208185018101929081019088841115614c25575f5ffd5b6020860192505b83831015614cbe5782516001600160401b03811115614c49575f5ffd5b86016040818b03601f19011215614c5e575f5ffd5b614c66613f23565b602082015160ff81168114614c79575f5ffd5b815260408201516001600160401b03811115614c93575f5ffd5b614ca28c6020838601016149d6565b6020830152508084525050602082019150602083019250614c2c565b845250919695505050505050565b5f60018201614cdd57614cdd61451c565b5060010190565b60ff828116828216039081111561195d5761195d61451c565b6001815b6001841115614d3857808504811115614d1c57614d1c61451c565b6001841615614d2a57908102905b60019390931c928002614d01565b935093915050565b5f82614d4e5750600161195d565b81614d5a57505f61195d565b8160018114614d705760028114614d7a57614d96565b600191505061195d565b60ff841115614d8b57614d8b61451c565b50506001821b61195d565b5060208310610133831016604e8410600b8410161715614db9575081810a61195d565b614dc55f198484614cfd565b805f1904821115614dd857614dd861451c565b029392505050565b5f6127818383614d40565b5f82614df957614df96146e8565b50069056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00a2646970667358221220a27cbc0408f91e4fc6e91630d32a3e0ac92fd2bdc83f3071ab186e972a39cef364736f6c634300081c0033
Loading...
Loading
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
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.