Address Contract Partially Verified
Address
0xF54b696180903B8F3a1CaE532e5328ed0dfFA4CC
Balance
0.006907 ETH
Nonce
1
Code Size
6454 bytes
Creator
0x89613F32...0f76 at tx 0xae5202d6...8a6fea
Indexed Transactions
0
Contract Bytecode
6454 bytes
0x608060405260043610610134575f3560e01c8063806ad57e116100a8578063c4f987a51161006d578063c4f987a5146103bf578063c5b3ffe9146103de578063d239c97314610409578063e6adfe3714610428578063efd00e8a14610447578063fc82f0841461044f575f80fd5b8063806ad57e14610315578063877f210c14610334578063983c45cf14610353578063aa15664514610372578063c3170007146103a0575f80fd5b80634460d3cf116100f95780634460d3cf1461024657806345e0e412146102655780635af2e9fb146102845780635eae21fa146102a357806368c4ac26146102c2578063799bf3f914610300575f80fd5b80630a0f8168146101695780630c53c51c146101a457806321507b4e146101c457806327d7874c146101e35780632d0335ab14610204575f80fd5b366101655760405134907f5e168818916f1fd9e52c6751cc95b7117e0d0e2d5d4f3868f21ce415555b9b40905f90a2005b5f80fd5b348015610174575f80fd5b505f54610187906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6101b76101b2366004611402565b610463565b60405161019b919061152d565b3480156101cf575f80fd5b50600554610187906001600160a01b031681565b3480156101ee575f80fd5b506102026101fd366004611546565b610619565b005b34801561020f575f80fd5b5061023861021e366004611546565b6001600160a01b03165f9081526003602052604090205490565b60405190815260200161019b565b348015610251575f80fd5b50610202610260366004611546565b6106be565b348015610270575f80fd5b5061020261027f36600461155f565b610703565b34801561028f575f80fd5b5061020261029e366004611546565b6107f7565b3480156102ae575f80fd5b506102026102bd366004611594565b610842565b3480156102cd575f80fd5b506102f06102dc366004611546565b60066020525f908152604090205460ff1681565b604051901515815260200161019b565b34801561030b575f80fd5b5061023860045481565b348015610320575f80fd5b5061020261032f366004611546565b610895565b34801561033f575f80fd5b5061020261034e3660046115c9565b6108ca565b34801561035e575f80fd5b5061020261036d366004611602565b610a2b565b34801561037d575f80fd5b506102f061038c366004611546565b60016020525f908152604090205460ff1681565b3480156103ab575f80fd5b506102026103ba366004611619565b610a59565b3480156103ca575f80fd5b506102026103d9366004611546565b610ad8565b3480156103e9575f80fd5b506102386103f8366004611546565b60076020525f908152604090205481565b348015610414575f80fd5b506102f0610423366004611546565b610b0a565b348015610433575f80fd5b50610202610442366004611619565b610b3a565b610202610bb4565b34801561045a575f80fd5b50610202610c54565b60408051606081810183526001600160a01b0388165f81815260036020908152908590205484528301529181018690526104a08782878787610cf5565b6104c55760405162461bcd60e51b81526004016104bc90611688565b60405180910390fd5b6001600160a01b0387165f908152600360205260409020546104e89060016116e4565b6001600160a01b0388165f90815260036020908152604080832093909355915190918291309161051c918b918d91016116f7565b60408051601f19818403018152908290526105369161172d565b5f604051808303815f865af19150503d805f811461056f576040519150601f19603f3d011682016040523d82523d5f602084013e610574565b606091505b5091509150816105d25760405162461bcd60e51b815260206004820152602360248201527f4549503731324d6574615472616e73616374696f6e3a20494e56414c49445f4360448201526210531360ea1b60648201526084016104bc565b7f5845892132946850460bff5a0083f71031bc5bf9aadcd40f1de79423eac9b10b89338a60405161060593929190611748565b60405180910390a198975050505050505050565b806001600160a01b0381166106405760405162461bcd60e51b81526004016104bc9061177c565b5f546001600160a01b031633146106695760405162461bcd60e51b81526004016104bc906117b3565b5f80546001600160a01b0319166001600160a01b0384169081179091556040519081527ff97cbb4246b709036319093e5ff31674b9f6759076d153e1bea1f60392170fc0906020015b60405180910390a15050565b5f546001600160a01b031633146106e75760405162461bcd60e51b81526004016104bc906117b3565b5f6106f28230610da9565b90506106ff823383610e9d565b5050565b3361070d81610b0a565b6107295760405162461bcd60e51b81526004016104bc906117ea565b6001600160a01b038082165f908152600760209081526040808320439055928616825260069052205460ff166107a15760405162461bcd60e51b815260206004820152601b60248201527f546f6b656e4875623a20554e535550504f525445445f544f4b454e000000000060448201526064016104bc565b6005546107bb90849083906001600160a01b031685610fe3565b60405182906001600160a01b0385169033907fceac81a6cfb44e1614ce02f28d4c280e6e9f4c9cf2585ab625f5e182caf7023d905f90a4505050565b5f546001600160a01b031633146108205760405162461bcd60e51b81526004016104bc906117b3565b600580546001600160a01b0319166001600160a01b0392909216919091179055565b5f546001600160a01b0316331461086b5760405162461bcd60e51b81526004016104bc906117b3565b6001600160a01b03919091165f908152600660205260409020805460ff1916911515919091179055565b5f546001600160a01b031633146108be5760405162461bcd60e51b81526004016104bc906117b3565b6108c78161113a565b50565b335f9081526001602081905260409091205460ff1615151461092e5760405162461bcd60e51b815260206004820152601c60248201527f416363657373436f6e74726f6c3a20574f524b45525f44454e4945440000000060448201526064016104bc565b61093783610b0a565b6109535760405162461bcd60e51b81526004016104bc906117ea565b6001600160a01b038084165f908152600760209081526040808320439055928516825260069052205460ff166109cb5760405162461bcd60e51b815260206004820152601b60248201527f546f6b656e4875623a20554e535550504f525445445f544f4b454e000000000060448201526064016104bc565b6005546109e590839085906001600160a01b031684610fe3565b80826001600160a01b0316846001600160a01b03167fceac81a6cfb44e1614ce02f28d4c280e6e9f4c9cf2585ab625f5e182caf7023d60405160405180910390a4505050565b5f546001600160a01b03163314610a545760405162461bcd60e51b81526004016104bc906117b3565b600455565b5f546001600160a01b03163314610a825760405162461bcd60e51b81526004016104bc906117b3565b5f5b60ff8116821115610ad357610ac183838360ff16818110610aa757610aa7611821565b9050602002016020810190610abc9190611546565b61113a565b80610acb81611835565b915050610a84565b505050565b5f546001600160a01b03163314610b015760405162461bcd60e51b81526004016104bc906117b3565b6108c781611229565b6004546001600160a01b0382165f90815260076020526040812054909190610b329043611853565b101592915050565b5f546001600160a01b03163314610b635760405162461bcd60e51b81526004016104bc906117b3565b5f5b60ff8116821115610ad357610ba283838360ff16818110610b8857610b88611821565b9050602002016020810190610b9d9190611546565b611229565b80610bac81611835565b915050610b65565b33610bbe81610b0a565b610bda5760405162461bcd60e51b81526004016104bc906117ea565b6001600160a01b038082165f9081526007602052604080822043905560055490519216913480156108fc0292909190818181858888f19350505050158015610c24573d5f803e3d5ffd5b50604051349033907f2f0094ad9640858ffa87c59b7086fb03a519c627e74993edab801eb7a1503f55905f90a350565b5f546001600160a01b03163314610c7d5760405162461bcd60e51b81526004016104bc906117b3565b4780610ccb5760405162461bcd60e51b815260206004820152601a60248201527f4e6f2045746865722062616c616e636520746f2072657363756500000000000060448201526064016104bc565b604051339082156108fc029083905f818181858888f193505050501580156106ff573d5f803e3d5ffd5b5f806001610d0a610d0588611318565b611394565b604080515f8152602081018083529290925260ff861690820152606081018790526080810186905260a0016020604051602081039080840390855afa158015610d55573d5f803e3d5ffd5b5050604051601f1901519150506001600160a01b038116610d885760405162461bcd60e51b81526004016104bc90611688565b866001600160a01b0316816001600160a01b03161491505095945050505050565b604080518082018252601281527162616c616e63654f6628616464726573732960701b60209182015281516001600160a01b03848116602480840191909152845180840390910181526044909201845291810180516001600160e01b03166370a0823160e01b17905291515f928392839290871691610e279161172d565b5f604051808303815f865af19150503d805f8114610e60576040519150601f19603f3d011682016040523d82523d5f602084013e610e65565b606091505b5090925090508115155f03610e7e575f92505050610e97565b80806020019051810190610e929190611866565b925050505b92915050565b604080518082018252601981527f7472616e7366657228616464726573732c75696e74323536290000000000000060209182015281516001600160a01b0385811660248301526044808301869052845180840390910181526064909201845291810180516001600160e01b031663a9059cbb60e01b17905291515f928392871691610f28919061172d565b5f604051808303815f865af19150503d805f8114610f61576040519150601f19603f3d011682016040523d82523d5f602084013e610f66565b606091505b5091509150818015610f90575080511580610f90575080806020019051810190610f90919061187d565b610fdc5760405162461bcd60e51b815260206004820152601f60248201527f5472616e7366657248656c7065723a205452414e534645525f4641494c45440060448201526064016104bc565b5050505050565b5f80856001600160a01b03166040518060600160405280602581526020016118996025913980516020909101206040516001600160a01b038089166024830152871660448201526064810186905260840160408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909416939093179092529051611072919061172d565b5f604051808303815f865af19150503d805f81146110ab576040519150601f19603f3d011682016040523d82523d5f602084013e6110b0565b606091505b50915091508180156110da5750805115806110da5750808060200190518101906110da919061187d565b6111325760405162461bcd60e51b8152602060048201526024808201527f5472616e7366657248656c7065723a205452414e534645525f46524f4d5f46416044820152631253115160e21b60648201526084016104bc565b505050505050565b806001600160a01b0381166111615760405162461bcd60e51b81526004016104bc9061177c565b6001600160a01b0382165f9081526001602052604090205460ff16156111d55760405162461bcd60e51b815260206004820152602360248201527f416363657373436f6e74726f6c3a20776f726b657220616c72656164792065786044820152621a5cdd60ea1b60648201526084016104bc565b6001600160a01b0382165f81815260016020818152604092839020805460ff191690921790915590519182527fb10d2a24a8c3686841e966f0c2c64c385cfaecb50a09b16aa3579bfcf3989dcd91016106b2565b806001600160a01b0381166112505760405162461bcd60e51b81526004016104bc9061177c565b6001600160a01b0382165f9081526001602081905260409091205460ff161515146112c85760405162461bcd60e51b815260206004820152602260248201527f416363657373436f6e74726f6c3a20776f726b6572206e6f7420646574656374604482015261195960f21b60648201526084016104bc565b6001600160a01b0382165f81815260016020908152604091829020805460ff1916905590519182527f6cfb0504498d3a8155a2a3dd5f41940ad5ab571197ac70f6d6948d189f6a0d2791016106b2565b5f6040518060800160405280604381526020016118be6043913980516020918201208351848301516040808701518051908601209051611377950193845260208401929092526001600160a01b03166040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b5f61139e60025490565b60405161190160f01b6020820152602281019190915260428101839052606201611377565b80356001600160a01b03811681146113d9575f80fd5b919050565b634e487b7160e01b5f52604160045260245ffd5b803560ff811681146113d9575f80fd5b5f805f805f60a08688031215611416575f80fd5b61141f866113c3565b9450602086013567ffffffffffffffff8082111561143b575f80fd5b818801915088601f83011261144e575f80fd5b813581811115611460576114606113de565b604051601f8201601f19908116603f01168101908382118183101715611488576114886113de565b816040528281528b60208487010111156114a0575f80fd5b826020860160208301375f60208483010152809850505050505060408601359250606086013591506114d4608087016113f2565b90509295509295909350565b5f5b838110156114fa5781810151838201526020016114e2565b50505f910152565b5f81518084526115198160208601602086016114e0565b601f01601f19169290920160200192915050565b602081525f61153f6020830184611502565b9392505050565b5f60208284031215611556575f80fd5b61153f826113c3565b5f8060408385031215611570575f80fd5b611579836113c3565b946020939093013593505050565b80151581146108c7575f80fd5b5f80604083850312156115a5575f80fd5b6115ae836113c3565b915060208301356115be81611587565b809150509250929050565b5f805f606084860312156115db575f80fd5b6115e4846113c3565b92506115f2602085016113c3565b9150604084013590509250925092565b5f60208284031215611612575f80fd5b5035919050565b5f806020838503121561162a575f80fd5b823567ffffffffffffffff80821115611641575f80fd5b818501915085601f830112611654575f80fd5b813581811115611662575f80fd5b8660208260051b8501011115611676575f80fd5b60209290920196919550909350505050565b60208082526028908201527f4549503731324d6574615472616e73616374696f6e3a20494e56414c49445f5360408201526749474e415455524560c01b606082015260800190565b634e487b7160e01b5f52601160045260245ffd5b80820180821115610e9757610e976116d0565b5f83516117088184602088016114e0565b60609390931b6bffffffffffffffffffffffff19169190920190815260140192915050565b5f825161173e8184602087016114e0565b9190910192915050565b6001600160a01b038481168252831660208201526060604082018190525f9061177390830184611502565b95945050505050565b6020808252601e908201527f416363657373436f6e74726f6c3a20494e56414c49445f414444524553530000604082015260600190565b60208082526019908201527f416363657373436f6e74726f6c3a2043454f5f44454e49454400000000000000604082015260600190565b6020808252601a908201527f546f6b656e4875623a204445504f5349545f434f4f4c444f574e000000000000604082015260600190565b634e487b7160e01b5f52603260045260245ffd5b5f60ff821660ff810361184a5761184a6116d0565b60010192915050565b81810381811115610e9757610e976116d0565b5f60208284031215611876575f80fd5b5051919050565b5f6020828403121561188d575f80fd5b815161153f8161158756fe7472616e7366657246726f6d28616464726573732c616464726573732c75696e74323536294d6574615472616e73616374696f6e2875696e74323536206e6f6e63652c616464726573732066726f6d2c62797465732066756e6374696f6e5369676e617475726529a2646970667358221220c5703897802bf6ac1308c073afe5f1f8c1a5eb11c535ebe17afb21ca6f999b0f64736f6c63430008150033
Verified Source Code Partial Match
Compiler: v0.8.21+commit.d9974bed
EVM: shanghai
Optimization: Yes (200 runs)
TokenHub.sol 216 lines
// SPDX-License-Identifier: -- DG --
pragma solidity =0.8.21;
import "./Interfaces.sol";
import "./TransferHelper.sol";
import "./AccessController.sol";
import "./EIP712MetaTransaction.sol";
contract TokenHub is
AccessController,
TransferHelper,
EIP712MetaTransaction
{
uint256 public forwardFrame;
address public forwardAddress;
receive()
external
payable
{
emit ReceiveNative(
msg.value
);
}
mapping(address => bool) public supportedTokens;
mapping(address => uint256) public forwardFrames;
event Forward(
address indexed depositorAddress,
address indexed paymentTokenAddress,
uint256 indexed paymentTokenAmount
);
event ForwardNative(
address indexed depositorAddress,
uint256 indexed paymentTokenAmount
);
event ReceiveNative(
uint256 indexed nativeAmount
);
constructor(
address _defaultToken,
uint256 _defaultFrame,
address _defaultAddress
)
EIP712Base(
"TokenHub",
"v3.0"
)
{
forwardFrame = _defaultFrame;
forwardAddress = _defaultAddress;
supportedTokens[_defaultToken] = true;
}
function forwardNative()
external
payable
{
address _depositorAddress = msg.sender;
require(
canDepositAgain(_depositorAddress),
"TokenHub: DEPOSIT_COOLDOWN"
);
forwardFrames[_depositorAddress] = block.number;
payable(forwardAddress).transfer(
msg.value
);
emit ForwardNative(
msg.sender,
msg.value
);
}
function forwardTokens(
address _paymentToken,
uint256 _paymentTokenAmount
)
external
{
address _depositorAddress = msg.sender;
require(
canDepositAgain(_depositorAddress),
"TokenHub: DEPOSIT_COOLDOWN"
);
forwardFrames[_depositorAddress] = block.number;
require(
supportedTokens[_paymentToken],
"TokenHub: UNSUPPORTED_TOKEN"
);
safeTransferFrom(
_paymentToken,
_depositorAddress,
forwardAddress,
_paymentTokenAmount
);
emit Forward(
msg.sender,
_paymentToken,
_paymentTokenAmount
);
}
function forwardTokensByWorker(
address _depositorAddress,
address _paymentTokenAddress,
uint256 _paymentTokenAmount
)
external
onlyWorker
{
require(
canDepositAgain(_depositorAddress),
"TokenHub: DEPOSIT_COOLDOWN"
);
forwardFrames[_depositorAddress] = block.number;
require(
supportedTokens[_paymentTokenAddress],
"TokenHub: UNSUPPORTED_TOKEN"
);
safeTransferFrom(
_paymentTokenAddress,
_depositorAddress,
forwardAddress,
_paymentTokenAmount
);
emit Forward(
_depositorAddress,
_paymentTokenAddress,
_paymentTokenAmount
);
}
function changeForwardFrame(
uint256 _newDepositFrame
)
external
onlyCEO
{
forwardFrame = _newDepositFrame;
}
function changeForwardAddress(
address _newForwardAddress
)
external
onlyCEO
{
forwardAddress = _newForwardAddress;
}
function changeSupportedToken(
address _tokenAddress,
bool _supportStatus
)
external
onlyCEO
{
supportedTokens[_tokenAddress] = _supportStatus;
}
function canDepositAgain(
address _depositorAddress
)
public
view
returns (bool)
{
return block.number - forwardFrames[_depositorAddress] >= forwardFrame;
}
function rescueToken(
address _tokenAddress
)
external
onlyCEO
{
uint256 tokenBalance = safeBalance(
_tokenAddress,
address(this)
);
safeTransfer(
_tokenAddress,
msg.sender,
tokenBalance
);
}
function rescueNative()
external
onlyCEO
{
uint256 etherBalance = address(this).balance;
require(etherBalance > 0, "No Ether balance to rescue");
payable(msg.sender).transfer(etherBalance);
}
}
EIP712Base.sol 68 lines
// SPDX-License-Identifier: -- DG --
pragma solidity =0.8.21;
contract EIP712Base {
struct EIP712Domain {
string name;
string version;
uint256 chainId;
address verifyingContract;
}
bytes32 internal constant EIP712_DOMAIN_TYPEHASH = keccak256(
bytes(
"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
)
);
bytes32 internal domainSeperator;
constructor(
string memory _name,
string memory _version
) {
domainSeperator = keccak256(abi.encode(
EIP712_DOMAIN_TYPEHASH,
keccak256(bytes(_name)),
keccak256(bytes(_version)),
getChainID(),
address(this)
));
}
function getChainID()
internal
pure
returns (uint256 id)
{
assembly {
id := 1
}
}
function getDomainSeperator()
private
view
returns(bytes32)
{
return domainSeperator;
}
function toTypedMessageHash(
bytes32 _messageHash
)
internal
view
returns(bytes32)
{
return keccak256(
abi.encodePacked(
"\x19\x01",
getDomainSeperator(),
_messageHash
)
);
}
}
Interfaces.sol 82 lines
// SPDX-License-Identifier: -- DG --
pragma solidity =0.8.21;
interface ERC721 {
function ownerOf(
uint256 _tokenId
)
external
view
returns (address);
function transferFrom(
address _from,
address _to,
uint256 _tokenId
)
external;
}
interface ERC20 {
function approve(
address spender,
uint256 amount
)
external
returns (bool);
function burn(
uint256 _amount
)
external;
}
interface DGAccessories {
function issueTokens(
address[] calldata _beneficiaries,
uint256[] calldata _itemIds
)
external;
function encodeTokenId(
uint256 _itemId,
uint256 _issuedId
)
external
pure
returns (uint256 id);
function decodeTokenId(
uint256 _tokenId
)
external
pure
returns (
uint256 itemId,
uint256 issuedId
);
function items(
uint256 _id
)
external
view
returns (
string memory rarity,
uint256 maxSupply,
uint256 totalSupply,
uint256 price,
address beneficiary,
string memory metadata,
string memory contentHash
);
function itemsCount()
external
view
returns (uint256);
}
TransferHelper.sol 104 lines
// SPDX-License-Identifier: -- DG --
pragma solidity =0.8.21;
contract TransferHelper {
bytes4 private constant TRANSFER = bytes4(
keccak256(
bytes(
"transfer(address,uint256)" // 0xa9059cbb
)
)
);
bytes4 private constant TRANSFER_FROM = bytes4(
keccak256(
bytes(
"transferFrom(address,address,uint256)" // 0x23b872dd
)
)
);
bytes4 private constant BALANCE_OF = bytes4(
keccak256(
bytes(
"balanceOf(address)"
)
)
);
function safeTransfer(
address _token,
address _to,
uint256 _value
)
internal
{
(bool success, bytes memory data) = _token.call(
abi.encodeWithSelector(
TRANSFER, // 0xa9059cbb
_to,
_value
)
);
require(
success && (
data.length == 0 || abi.decode(
data, (bool)
)
),
"TransferHelper: TRANSFER_FAILED"
);
}
function safeTransferFrom(
address _token,
address _from,
address _to,
uint _value
)
internal
{
(bool success, bytes memory data) = _token.call(
abi.encodeWithSelector(
TRANSFER_FROM,
_from,
_to,
_value
)
);
require(
success && (
data.length == 0 || abi.decode(
data, (bool)
)
),
"TransferHelper: TRANSFER_FROM_FAILED"
);
}
function safeBalance(
address _token,
address _owner
)
internal
returns (uint256)
{
(bool success, bytes memory data) = _token.call(
abi.encodeWithSelector(
BALANCE_OF,
_owner
)
);
if (success == false) return 0;
return abi.decode(
data,
(uint256)
);
}
}
AccessController.sol 156 lines
// SPDX-License-Identifier: -- DG --
pragma solidity =0.8.21;
contract AccessController {
address public ceoAddress;
mapping (address => bool) public isWorker;
event CEOSet(
address newCEO
);
event WorkerAdded(
address newWorker
);
event WorkerRemoved(
address existingWorker
);
constructor() {
address creator = msg.sender;
ceoAddress = creator;
isWorker[creator] = true;
emit CEOSet(
creator
);
emit WorkerAdded(
creator
);
}
modifier onlyCEO() {
require(
msg.sender == ceoAddress,
"AccessControl: CEO_DENIED"
);
_;
}
modifier onlyWorker() {
require(
isWorker[msg.sender] == true,
"AccessControl: WORKER_DENIED"
);
_;
}
modifier nonZeroAddress(
address checkingAddress
) {
require(
checkingAddress != address(0x0),
"AccessControl: INVALID_ADDRESS"
);
_;
}
function setCEO(
address _newCEO
)
external
nonZeroAddress(_newCEO)
onlyCEO
{
ceoAddress = _newCEO;
emit CEOSet(
ceoAddress
);
}
function addWorker(
address _newWorker
)
external
onlyCEO
{
_addWorker(
_newWorker
);
}
function addWorkerBulk(
address[] calldata _newWorkers
)
external
onlyCEO
{
for (uint8 index = 0; index < _newWorkers.length; index++) {
_addWorker(_newWorkers[index]);
}
}
function _addWorker(
address _newWorker
)
internal
nonZeroAddress(_newWorker)
{
require(
isWorker[_newWorker] == false,
'AccessControl: worker already exist'
);
isWorker[_newWorker] = true;
emit WorkerAdded(
_newWorker
);
}
function removeWorker(
address _existingWorker
)
external
onlyCEO
{
_removeWorker(
_existingWorker
);
}
function removeWorkerBulk(
address[] calldata _workerArray
)
external
onlyCEO
{
for (uint8 index = 0; index < _workerArray.length; index++) {
_removeWorker(_workerArray[index]);
}
}
function _removeWorker(
address _existingWorker
)
internal
nonZeroAddress(_existingWorker)
{
require(
isWorker[_existingWorker] == true,
"AccessControl: worker not detected"
);
isWorker[_existingWorker] = false;
emit WorkerRemoved(
_existingWorker
);
}
}
EIP712MetaTransaction.sol 157 lines
// SPDX-License-Identifier: -- DG --
pragma solidity =0.8.21;
import "./EIP712Base.sol";
abstract contract EIP712MetaTransaction is EIP712Base {
bytes32 private constant META_TRANSACTION_TYPEHASH = keccak256(
bytes(
"MetaTransaction(uint256 nonce,address from,bytes functionSignature)"
)
);
event MetaTransactionExecuted(
address userAddress,
address payable relayerAddress,
bytes functionSignature
);
mapping(address => uint256) internal nonces;
struct MetaTransaction {
uint256 nonce;
address from;
bytes functionSignature;
}
function executeMetaTransaction(
address _userAddress,
bytes memory _functionSignature,
bytes32 _sigR,
bytes32 _sigS,
uint8 _sigV
)
public
payable
returns(bytes memory)
{
MetaTransaction memory metaTx = MetaTransaction(
{
nonce: nonces[_userAddress],
from: _userAddress,
functionSignature: _functionSignature
}
);
require(
verify(
_userAddress,
metaTx,
_sigR,
_sigS,
_sigV
), "EIP712MetaTransaction: INVALID_SIGNATURE"
);
nonces[_userAddress] =
nonces[_userAddress] + 1;
(bool success, bytes memory returnData) = address(this).call(
abi.encodePacked(
_functionSignature,
_userAddress
)
);
require(
success,
"EIP712MetaTransaction: INVALID_CALL"
);
emit MetaTransactionExecuted(
_userAddress,
payable(msg.sender),
_functionSignature
);
return returnData;
}
function hashMetaTransaction(
MetaTransaction memory _metaTx
)
internal
pure
returns (bytes32)
{
return keccak256(
abi.encode(
META_TRANSACTION_TYPEHASH,
_metaTx.nonce,
_metaTx.from,
keccak256(_metaTx.functionSignature)
)
);
}
function verify(
address _user,
MetaTransaction memory _metaTx,
bytes32 _sigR,
bytes32 _sigS,
uint8 _sigV
)
internal
view
returns (bool)
{
address signer = ecrecover(
toTypedMessageHash(
hashMetaTransaction(_metaTx)
),
_sigV,
_sigR,
_sigS
);
require(
signer != address(0x0),
"EIP712MetaTransaction: INVALID_SIGNATURE"
);
return signer == _user;
}
function msgSender()
internal
view
returns(address sender)
{
if (msg.sender == address(this)) {
bytes memory array = msg.data;
uint256 index = msg.data.length;
assembly {
// Load the 32 bytes word from memory with the address on the lower 20 bytes, and mask those.
sender := and(mload(add(array, index)), 0xffffffffffffffffffffffffffffffffffffffff)
}
} else {
sender = msg.sender;
}
return sender;
}
function getNonce(
address _user
)
external
view
returns(uint256 nonce)
{
nonce = nonces[_user];
}
}
Read Contract
canDepositAgain 0xd239c973 → bool
ceoAddress 0x0a0f8168 → address
forwardAddress 0x21507b4e → address
forwardFrame 0x799bf3f9 → uint256
forwardFrames 0xc5b3ffe9 → uint256
getNonce 0x2d0335ab → uint256
isWorker 0xaa156645 → bool
supportedTokens 0x68c4ac26 → bool
Write Contract 14 functions
These functions modify contract state and require a wallet transaction to execute.
addWorker 0x806ad57e
address _newWorker
addWorkerBulk 0xc3170007
address[] _newWorkers
changeForwardAddress 0x5af2e9fb
address _newForwardAddress
changeForwardFrame 0x983c45cf
uint256 _newDepositFrame
changeSupportedToken 0x5eae21fa
address _tokenAddress
bool _supportStatus
executeMetaTransaction 0x0c53c51c
address _userAddress
bytes _functionSignature
bytes32 _sigR
bytes32 _sigS
uint8 _sigV
returns: bytes
forwardNative 0xefd00e8a
No parameters
forwardTokens 0x45e0e412
address _paymentToken
uint256 _paymentTokenAmount
forwardTokensByWorker 0x877f210c
address _depositorAddress
address _paymentTokenAddress
uint256 _paymentTokenAmount
removeWorker 0xc4f987a5
address _existingWorker
removeWorkerBulk 0xe6adfe37
address[] _workerArray
rescueNative 0xfc82f084
No parameters
rescueToken 0x4460d3cf
address _tokenAddress
setCEO 0x27d7874c
address _newCEO
Recent Transactions
No transactions found for this address