编译器
0.8.21+commit.d9974bed
文件 1 的 45:Address.sol
pragma solidity ^0.8.1;
library Address {
function isContract(address account) internal view returns (bool) {
return account.code.length > 0;
}
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
文件 2 的 45:AddressString.sol
pragma solidity ^0.8.0;
library StringToAddress {
error InvalidAddressString();
function toAddress(string memory addressString) internal pure returns (address) {
bytes memory stringBytes = bytes(addressString);
uint160 addressNumber = 0;
uint8 stringByte;
if (stringBytes.length != 42 || stringBytes[0] != '0' || stringBytes[1] != 'x') revert InvalidAddressString();
for (uint256 i = 2; i < 42; ++i) {
stringByte = uint8(stringBytes[i]);
if ((stringByte >= 97) && (stringByte <= 102)) stringByte -= 87;
else if ((stringByte >= 65) && (stringByte <= 70)) stringByte -= 55;
else if ((stringByte >= 48) && (stringByte <= 57)) stringByte -= 48;
else revert InvalidAddressString();
addressNumber |= uint160(uint256(stringByte) << ((41 - i) << 2));
}
return address(addressNumber);
}
}
library AddressToString {
function toString(address address_) internal pure returns (string memory) {
bytes memory addressBytes = abi.encodePacked(address_);
bytes memory characters = '0123456789abcdef';
bytes memory stringBytes = new bytes(42);
stringBytes[0] = '0';
stringBytes[1] = 'x';
for (uint256 i; i < 20; ++i) {
stringBytes[2 + i * 2] = characters[uint8(addressBytes[i] >> 4)];
stringBytes[3 + i * 2] = characters[uint8(addressBytes[i] & 0x0f)];
}
return string(stringBytes);
}
}
文件 3 的 45:AddressWithChain.sol
pragma solidity 0.8.21;
import "./Asset.sol";
struct AddressWithChain{
bytes chainSelector;
address _address;
}
struct AssetHashWithSource {
AddressWithChain source;
bytes32 assetHash;
}
文件 4 的 45:Asset.sol
pragma solidity 0.8.21;
enum AssetType {
ERC721,
ERC1155,
ERC20,
Native,
ESE,
ERC721LazyMint
}
struct Asset {
address token;
uint256 tokenID;
uint256 amount;
AssetType assetType;
bytes data;
}
文件 5 的 45:AxelarCaller.sol
pragma solidity 0.8.21;
import { IAxelarGateway } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGateway.sol';
import { StringToAddress } from "@axelar-network/axelar-gmp-sdk-solidity/contracts/libs/AddressString.sol";
import { IAxelarGasService } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGasService.sol';
import "@openzeppelin/contracts/utils/Strings.sol";
import "../../types/AddressWithChain.sol";
import "../../interfaces/ICallerBase.sol";
import "./AxelarGatewayBase.sol";
abstract contract AxelarCaller is AxelarGatewayBase, ICallerBase {
using Strings for address;
using StringToAddress for string;
bytes32 constant public AXELAR_CALLER_IDENTIFIER = keccak256("AXELAR_CALLER");
function _sendAxelarMessage(
AddressWithChain memory destination,
bytes memory payload,
uint256 gas
) internal {
string memory destinationString = destination._address.toHexString();
string memory chainSelector = abi.decode(destination.chainSelector, (string));
gasService.payNativeGasForContractCall{value: gas}(
address(this),
chainSelector,
destinationString,
payload,
tx.origin
);
gateway.callContract(
chainSelector,
destinationString,
payload
);
emit CrosschainSend(AXELAR_CALLER_IDENTIFIER, destination, abi.encode(gas));
}
function execute(
bytes32 commandId,
string calldata sourceChain,
string calldata sourceAddress,
bytes calldata payload
) external {
bytes32 payloadHash = keccak256(payload);
if (!gateway.validateContractCall(commandId, sourceChain, sourceAddress, payloadHash))
revert NotApprovedByGateway();
AddressWithChain memory source = AddressWithChain({
chainSelector: abi.encode(sourceChain),
_address: sourceAddress.toAddress()
});
_execute(source, payload);
emit CrosschainReceive(AXELAR_CALLER_IDENTIFIER, source, "");
}
function _execute(
AddressWithChain memory source,
bytes calldata payload
) internal virtual;
}
文件 6 的 45:AxelarCallerEeseeMessageInterface.sol
pragma solidity 0.8.21;
import "../../../abstract/crosschain/AxelarCaller.sol";
import "../../../libraries/CompareAddressWithChain.sol";
import "./EeseeMessageInterface.sol";
abstract contract AxelarCallerEeseeMessageInterface is AxelarCaller, EeseeMessageInterface {
function _sendMessage(
address ,
AddressWithChain memory destination,
bytes memory payload,
uint256 gas,
bytes calldata
) internal override {
_sendAxelarMessage(destination, payload, gas);
}
function _execute(AddressWithChain memory source, bytes calldata data) internal override {
_receiveMessage(source, data);
}
}
文件 7 的 45:AxelarGatewayBase.sol
pragma solidity 0.8.21;
import { IAxelarGateway } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGateway.sol';
import { IAxelarGasService } from '@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGasService.sol';
abstract contract AxelarGatewayBase {
IAxelarGateway public immutable gateway;
IAxelarGasService immutable public gasService;
error InvalidGasService();
error InvalidGateway();
error NotApprovedByGateway();
constructor(IAxelarGateway _gateway, IAxelarGasService _gasService) {
if(address(_gateway) == address(0)) revert InvalidGateway();
if(address(_gasService) == address(0)) revert InvalidGasService();
gateway = _gateway;
gasService = _gasService;
}
}
文件 8 的 45:Call.sol
pragma solidity 0.8.21;
struct Call {
address target;
bytes callData;
}
文件 9 的 45:CompareAddressWithChain.sol
pragma solidity 0.8.21;
import "../types/AddressWithChain.sol";
import "./CompareBytes.sol";
error InvalidDestination();
library CompareAddressWithChain {
using CompareBytes for bytes;
function eq(AddressWithChain memory a, AddressWithChain memory b) internal pure returns (bool){
return (a._address == b._address) && a.chainSelector.eq(b.chainSelector);
}
}
文件 10 的 45:CompareBytes.sol
pragma solidity 0.8.21;
library CompareBytes {
function eq(bytes memory a, bytes memory b) internal pure returns (bool){
return (a.length == b.length) && (keccak256(a) == keccak256(b));
}
}
文件 11 的 45:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
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;
}
}
文件 12 的 45:ERC1155Holder.sol
pragma solidity ^0.8.0;
import "./ERC1155Receiver.sol";
contract ERC1155Holder is ERC1155Receiver {
function onERC1155Received(
address,
address,
uint256,
uint256,
bytes memory
) public virtual override returns (bytes4) {
return this.onERC1155Received.selector;
}
function onERC1155BatchReceived(
address,
address,
uint256[] memory,
uint256[] memory,
bytes memory
) public virtual override returns (bytes4) {
return this.onERC1155BatchReceived.selector;
}
}
文件 13 的 45:ERC1155Receiver.sol
pragma solidity ^0.8.0;
import "../IERC1155Receiver.sol";
import "../../../utils/introspection/ERC165.sol";
abstract contract ERC1155Receiver is ERC165, IERC1155Receiver {
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return interfaceId == type(IERC1155Receiver).interfaceId || super.supportsInterface(interfaceId);
}
}
文件 14 的 45:ERC165.sol
pragma solidity ^0.8.0;
import "./IERC165.sol";
abstract contract ERC165 is IERC165 {
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
文件 15 的 45:ERC2771Context.sol
pragma solidity ^0.8.9;
import "../utils/Context.sol";
abstract contract ERC2771Context is Context {
address private immutable _trustedForwarder;
constructor(address trustedForwarder) {
_trustedForwarder = trustedForwarder;
}
function isTrustedForwarder(address forwarder) public view virtual returns (bool) {
return forwarder == _trustedForwarder;
}
function _msgSender() internal view virtual override returns (address) {
uint256 calldataLength = msg.data.length;
uint256 contextSuffixLength = _contextSuffixLength();
if (isTrustedForwarder(msg.sender) && calldataLength >= contextSuffixLength) {
return address(bytes20(msg.data[calldataLength - contextSuffixLength:]));
} else {
return super._msgSender();
}
}
function _msgData() internal view virtual override returns (bytes calldata) {
uint256 calldataLength = msg.data.length;
uint256 contextSuffixLength = _contextSuffixLength();
if (isTrustedForwarder(msg.sender) && calldataLength >= contextSuffixLength) {
return msg.data[:calldataLength - contextSuffixLength];
} else {
return super._msgData();
}
}
function _contextSuffixLength() internal view virtual override returns (uint256) {
return 20;
}
}
文件 16 的 45:ERC721Holder.sol
pragma solidity ^0.8.0;
import "../IERC721Receiver.sol";
contract ERC721Holder is IERC721Receiver {
function onERC721Received(address, address, uint256, bytes memory) public virtual override returns (bytes4) {
return this.onERC721Received.selector;
}
}
文件 17 的 45:EeseeAssetSpokeAxelar.sol
pragma solidity 0.8.21;
import "../abstract/EeseeAssetSpokeBase.sol";
import "../abstract/AxelarCallerEeseeMessageInterface.sol";
contract EeseeAssetSpokeAxelar is EeseeAssetSpokeBase, AxelarCallerEeseeMessageInterface {
constructor(
IEeseeAccessManager _accessManager,
bytes memory _currentChainSelector,
AddressWithChain memory _eeseeAssetHub,
IRoyaltyEngineV1 _royaltyEngine,
IAxelarGateway _gateway,
IAxelarGasService _gasService,
address trustedForwarder
) EeseeAssetSpokeBase(_accessManager, _currentChainSelector, _eeseeAssetHub, _royaltyEngine, trustedForwarder) AxelarGatewayBase(_gateway, _gasService) {}
}
文件 18 的 45:EeseeAssetSpokeBase.sol
pragma solidity 0.8.21;
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/metatx/ERC2771Context.sol";
import "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";
import "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";
import "../../../libraries/CompareAddressWithChain.sol";
import "../../../types/Call.sol";
import "../../../types/Asset.sol";
import "../../../interfaces/IEeseeAssetSpoke.sol";
import "../../../interfaces/IRoyaltyEngineV1.sol";
import "../../../abstract/roles/EeseePausable.sol";
import "./EeseeMessageInterface.sol";
import "../../../errors/EeseeErrors.sol";
abstract contract EeseeAssetSpokeBase is IEeseeAssetSpoke, ERC2771Context, ERC721Holder, ERC1155Holder, EeseePausable, EeseeMessageInterface {
using SafeERC20 for IERC20;
using CompareAddressWithChain for AddressWithChain;
AddressWithChain public eeseeSpoke;
AddressWithChain public eeseeAssetHub;
IRoyaltyEngineV1 immutable private royaltyEngine;
mapping(bytes32 => Asset) public assetsStorage;
mapping(address => mapping(bytes32 => uint256)) public stuckAmount;
event Stuck(
Asset asset,
bytes32 indexed assetHash,
address indexed recipient,
bytes err
);
event Unstuck(
Asset asset,
bytes32 indexed assetHash,
address indexed sender,
address indexed recipient
);
error InvalidConstructor();
error InvalidSender();
error InvalidInterface();
error InvalidTokenID();
error InvalidAsset();
error InvalidRecipient();
error OnlySelf();
error NoAssetsStuck();
error TransferNotSuccessful();
error InvalidAssetsLength();
modifier onlySelf() {
if (msg.sender != address(this)) revert OnlySelf();
_;
}
constructor(
IEeseeAccessManager _accessManager,
bytes memory _currentChainSelector,
AddressWithChain memory _eeseeAssetHub,
IRoyaltyEngineV1 _royaltyEngine,
address trustedForwarder
) ERC2771Context(trustedForwarder) EeseeRoleHandler(_accessManager) {
if(
_eeseeAssetHub._address == address(0) ||
address(_royaltyEngine) == address(0)
) revert InvalidConstructor();
eeseeSpoke = AddressWithChain({chainSelector: _currentChainSelector, _address: address(this)});
eeseeAssetHub = _eeseeAssetHub;
royaltyEngine = _royaltyEngine;
}
function wrap(
Asset[] calldata assets,
Call[] calldata crosschainCalls,
address fallbackRecipient,
bytes calldata additionalData
) whenNotPaused external payable returns(uint256 gasPaid){
if(assets.length == 0) revert InvalidAssetsLength();
if(fallbackRecipient == address(0)) revert InvalidRecipient();
address msgSender = _msgSender();
bytes32[] memory assetHashes; uint256[] memory amounts; bytes[] memory royaltyData;
(assetHashes, amounts, royaltyData, gasPaid) = _wrap(assets, msgSender);
_sendMessage(
msgSender,
eeseeAssetHub,
abi.encode(assetHashes, amounts, royaltyData, crosschainCalls, fallbackRecipient),
gasPaid,
additionalData
);
}
function unstuck(bytes32 stuckAssetHash, address recipient) external returns(Asset memory asset){
if(recipient == address(0)) revert InvalidRecipient();
address msgSender = _msgSender();
uint256 _stuckAmount = stuckAmount[msgSender][stuckAssetHash];
if(_stuckAmount == 0) revert NoAssetsStuck();
delete stuckAmount[msgSender][stuckAssetHash];
asset = this._transferAssetTo(stuckAssetHash, _stuckAmount, recipient);
emit Unstuck(asset, stuckAssetHash, msgSender, recipient);
}
function getTokenIdL2(Asset calldata asset) external view returns (uint256) {
return getTokenIdL2(getAssetHash(asset));
}
function getTokenIdL2(bytes32 assetHash) public view returns (uint256) {
AssetHashWithSource memory assetHashWithSource = AssetHashWithSource(eeseeSpoke, assetHash);
return uint256(keccak256(abi.encode(assetHashWithSource)));
}
function getAssetHash(Asset calldata asset) public pure returns (bytes32) {
return keccak256(abi.encode(asset.token, asset.tokenID, asset.assetType));
}
function _receiveMessage(AddressWithChain memory source, bytes memory data) internal override {
if(!source.eq(eeseeAssetHub)) revert InvalidSender();
(bytes32[] memory assetHashes, uint256[] memory amounts, address recipient) = abi.decode(data, (bytes32[], uint256[], address));
for(uint256 i; i < assetHashes.length;){
try this._transferAssetTo(assetHashes[i], amounts[i], recipient) returns (Asset memory asset) {
emit Unwrap(asset, assetHashes[i], recipient);
} catch (bytes memory err) {
Asset memory asset = assetsStorage[assetHashes[i]];
asset.amount = amounts[i];
stuckAmount[recipient][assetHashes[i]] += amounts[i];
emit Stuck(asset, assetHashes[i], recipient, err);
}
unchecked{ ++i; }
}
}
function _transferAssetTo(bytes32 assetHash, uint256 amount, address to) external onlySelf returns(Asset memory asset){
asset = assetsStorage[assetHash];
if(asset.amount < amount) revert InvalidAmount();
assetsStorage[assetHash].amount = asset.amount - amount;
asset.amount = amount;
if (asset.assetType == AssetType.ERC721) {
IERC721(asset.token).safeTransferFrom(address(this), to, asset.tokenID);
} else if (asset.assetType == AssetType.ERC1155) {
IERC1155(asset.token).safeTransferFrom(address(this), to, asset.tokenID, amount, "");
} else if (asset.assetType == AssetType.ERC20) {
IERC20(asset.token).safeTransfer(to, amount);
} else {
(bool success,) = to.call{value: amount}("");
if(!success) revert TransferNotSuccessful();
}
}
function _msgSender() internal view override(Context, ERC2771Context) returns (address) {
return ERC2771Context._msgSender();
}
function _msgData() internal view override(Context, ERC2771Context) returns (bytes calldata) {
return ERC2771Context._msgData();
}
function _contextSuffixLength() internal view override(Context, ERC2771Context) returns (uint256) {
return ERC2771Context._contextSuffixLength();
}
function _wrap(
Asset[] calldata assets,
address msgSender
) private returns (bytes32[] memory assetHashes, uint256[] memory amounts, bytes[] memory royaltyData, uint256 valueLeft){
assetHashes = new bytes32[](assets.length);
amounts = new uint256[](assets.length);
royaltyData = new bytes[](assets.length);
valueLeft = msg.value;
for(uint256 i; i < assets.length;){
(assetHashes[i], royaltyData[i], amounts[i], valueLeft) = _transferAssetFrom(assets[i], msgSender, valueLeft);
unchecked{ ++i; }
}
}
function _transferAssetFrom(
Asset calldata asset,
address msgSender,
uint256 availableValue
) private returns(bytes32 assetHash, bytes memory royaltyData, uint256 amount, uint256 valueLeft){
valueLeft = availableValue;
if (asset.assetType == AssetType.ERC721) {
if(asset.amount != 1) revert InvalidAmount();
{
(bool success, bytes memory res) = asset.token.staticcall(abi.encodeWithSelector(IERC165.supportsInterface.selector, type(IERC721).interfaceId));
if(!success || abi.decode(res, (bool)) == false) revert InvalidInterface();
(address payable[] memory royaltyRecipients, uint256[] memory royaltyAmounts) = royaltyEngine.getRoyalty(asset.token, asset.tokenID, 10000);
royaltyData = abi.encode(royaltyRecipients, royaltyAmounts);
}
amount = 1;
IERC721(asset.token).safeTransferFrom(msgSender, address(this), asset.tokenID);
} else if (asset.assetType == AssetType.ERC1155) {
if(asset.amount == 0) revert InvalidAmount();
{
(bool success, bytes memory res) = asset.token.staticcall(abi.encodeWithSelector(IERC165.supportsInterface.selector, type(IERC1155).interfaceId));
if(!success || abi.decode(res, (bool)) == false) revert InvalidInterface();
(address payable[] memory royaltyRecipients, uint256[] memory royaltyAmounts) = royaltyEngine.getRoyalty(asset.token, asset.tokenID, 10000);
royaltyData = abi.encode(royaltyRecipients, royaltyAmounts);
}
amount = asset.amount;
IERC1155(asset.token).safeTransferFrom(msgSender, address(this), asset.tokenID, asset.amount, "");
} else if (asset.assetType == AssetType.ERC20) {
(bool success, bytes memory res) = asset.token.staticcall(abi.encodeWithSelector(IERC165.supportsInterface.selector, type(IERC721).interfaceId));
if(success && abi.decode(res, (bool)) == true) revert InvalidInterface();
if(asset.tokenID != 0) revert InvalidTokenID();
uint256 balanceBefore = IERC20(asset.token).balanceOf(address(this));
IERC20(asset.token).safeTransferFrom(msgSender, address(this), asset.amount);
uint256 balanceAfter = IERC20(asset.token).balanceOf(address(this));
amount = balanceAfter - balanceBefore;
if(amount == 0) revert InvalidAmount();
} else if (asset.assetType == AssetType.Native) {
if(asset.amount == 0) revert InvalidAmount();
if(availableValue < asset.amount) revert InsufficientValue();
if(asset.token != address(0)) revert InvalidToken();
if(asset.tokenID != 0) revert InvalidTokenID();
unchecked{ valueLeft -= asset.amount; }
amount = asset.amount;
} else revert InvalidAsset();
Asset memory newAsset = Asset({
token: asset.token,
tokenID: asset.tokenID,
amount: amount,
assetType: asset.assetType,
data: ""
});
assetHash = getAssetHash(asset);
emit Wrap(newAsset, assetHash, msgSender);
newAsset.amount += assetsStorage[assetHash].amount;
assetsStorage[assetHash] = newAsset;
}
}
文件 19 的 45:EeseeErrors.sol
pragma solidity 0.8.21;
error InvalidToken();
error InvalidAmount();
error InsufficientValue();
文件 20 的 45:EeseeMessageInterface.sol
pragma solidity 0.8.21;
import "../../../types/AddressWithChain.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
abstract contract EeseeMessageInterface {
function _sendMessage(
address msgSender,
AddressWithChain memory destination,
bytes memory payload,
uint256 gas,
bytes calldata additionalData
) internal virtual;
function _receiveMessage(AddressWithChain memory source, bytes memory data) internal virtual;
}
文件 21 的 45:EeseePausable.sol
pragma solidity 0.8.21;
import "@openzeppelin/contracts/security/Pausable.sol";
import "./EeseeRoleHandler.sol";
abstract contract EeseePausable is Pausable, EeseeRoleHandler {
bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
modifier onlyPauser(){
_validateRole(PAUSER_ROLE, _msgSender());
_;
}
function pause() onlyPauser external virtual {
_pause();
}
function unpause() onlyPauser external virtual {
_unpause();
}
}
文件 22 的 45:EeseeRoleHandler.sol
pragma solidity 0.8.21;
import "@openzeppelin/contracts/utils/Context.sol";
import "../../interfaces/IEeseeAccessManager.sol";
abstract contract EeseeRoleHandler is Context {
IEeseeAccessManager public immutable accessManager;
error CallerNotAuthorized();
error InvalidAccessManager();
constructor(IEeseeAccessManager _accessManager) {
if(address(_accessManager) == address(0)) revert InvalidAccessManager();
accessManager = _accessManager;
}
modifier onlyRole(bytes32 role){
_validateRole(role, _msgSender());
_;
}
function _hasRole(bytes32 role, address _addr) internal view virtual returns (bool) {
return accessManager.hasRole(role, _addr);
}
function _validateRole(bytes32 role, address _addr) internal view {
if(!_hasRole(role, _addr)) revert CallerNotAuthorized();
}
}
文件 23 的 45:IAxelarGasService.sol
pragma solidity ^0.8.0;
import { IUpgradable } from '../interfaces/IUpgradable.sol';
interface IAxelarGasService is IUpgradable {
error NothingReceived();
error InvalidAddress();
error NotCollector();
error InvalidAmounts();
event GasPaidForContractCall(
address indexed sourceAddress,
string destinationChain,
string destinationAddress,
bytes32 indexed payloadHash,
address gasToken,
uint256 gasFeeAmount,
address refundAddress
);
event GasPaidForContractCallWithToken(
address indexed sourceAddress,
string destinationChain,
string destinationAddress,
bytes32 indexed payloadHash,
string symbol,
uint256 amount,
address gasToken,
uint256 gasFeeAmount,
address refundAddress
);
event NativeGasPaidForContractCall(
address indexed sourceAddress,
string destinationChain,
string destinationAddress,
bytes32 indexed payloadHash,
uint256 gasFeeAmount,
address refundAddress
);
event NativeGasPaidForContractCallWithToken(
address indexed sourceAddress,
string destinationChain,
string destinationAddress,
bytes32 indexed payloadHash,
string symbol,
uint256 amount,
uint256 gasFeeAmount,
address refundAddress
);
event GasPaidForExpressCall(
address indexed sourceAddress,
string destinationChain,
string destinationAddress,
bytes32 indexed payloadHash,
address gasToken,
uint256 gasFeeAmount,
address refundAddress
);
event GasPaidForExpressCallWithToken(
address indexed sourceAddress,
string destinationChain,
string destinationAddress,
bytes32 indexed payloadHash,
string symbol,
uint256 amount,
address gasToken,
uint256 gasFeeAmount,
address refundAddress
);
event NativeGasPaidForExpressCall(
address indexed sourceAddress,
string destinationChain,
string destinationAddress,
bytes32 indexed payloadHash,
uint256 gasFeeAmount,
address refundAddress
);
event NativeGasPaidForExpressCallWithToken(
address indexed sourceAddress,
string destinationChain,
string destinationAddress,
bytes32 indexed payloadHash,
string symbol,
uint256 amount,
uint256 gasFeeAmount,
address refundAddress
);
event GasAdded(
bytes32 indexed txHash,
uint256 indexed logIndex,
address gasToken,
uint256 gasFeeAmount,
address refundAddress
);
event NativeGasAdded(bytes32 indexed txHash, uint256 indexed logIndex, uint256 gasFeeAmount, address refundAddress);
event ExpressGasAdded(
bytes32 indexed txHash,
uint256 indexed logIndex,
address gasToken,
uint256 gasFeeAmount,
address refundAddress
);
event NativeExpressGasAdded(
bytes32 indexed txHash,
uint256 indexed logIndex,
uint256 gasFeeAmount,
address refundAddress
);
event Refunded(
bytes32 indexed txHash,
uint256 indexed logIndex,
address payable receiver,
address token,
uint256 amount
);
function payGasForContractCall(
address sender,
string calldata destinationChain,
string calldata destinationAddress,
bytes calldata payload,
address gasToken,
uint256 gasFeeAmount,
address refundAddress
) external;
function payGasForContractCallWithToken(
address sender,
string calldata destinationChain,
string calldata destinationAddress,
bytes calldata payload,
string calldata symbol,
uint256 amount,
address gasToken,
uint256 gasFeeAmount,
address refundAddress
) external;
function payNativeGasForContractCall(
address sender,
string calldata destinationChain,
string calldata destinationAddress,
bytes calldata payload,
address refundAddress
) external payable;
function payNativeGasForContractCallWithToken(
address sender,
string calldata destinationChain,
string calldata destinationAddress,
bytes calldata payload,
string calldata symbol,
uint256 amount,
address refundAddress
) external payable;
function payGasForExpressCall(
address sender,
string calldata destinationChain,
string calldata destinationAddress,
bytes calldata payload,
address gasToken,
uint256 gasFeeAmount,
address refundAddress
) external;
function payGasForExpressCallWithToken(
address sender,
string calldata destinationChain,
string calldata destinationAddress,
bytes calldata payload,
string calldata symbol,
uint256 amount,
address gasToken,
uint256 gasFeeAmount,
address refundAddress
) external;
function payNativeGasForExpressCall(
address sender,
string calldata destinationChain,
string calldata destinationAddress,
bytes calldata payload,
address refundAddress
) external payable;
function payNativeGasForExpressCallWithToken(
address sender,
string calldata destinationChain,
string calldata destinationAddress,
bytes calldata payload,
string calldata symbol,
uint256 amount,
address refundAddress
) external payable;
function addGas(
bytes32 txHash,
uint256 logIndex,
address gasToken,
uint256 gasFeeAmount,
address refundAddress
) external;
function addNativeGas(
bytes32 txHash,
uint256 logIndex,
address refundAddress
) external payable;
function addExpressGas(
bytes32 txHash,
uint256 logIndex,
address gasToken,
uint256 gasFeeAmount,
address refundAddress
) external;
function addNativeExpressGas(
bytes32 txHash,
uint256 logIndex,
address refundAddress
) external payable;
function collectFees(
address payable receiver,
address[] calldata tokens,
uint256[] calldata amounts
) external;
function refund(
bytes32 txHash,
uint256 logIndex,
address payable receiver,
address token,
uint256 amount
) external;
function gasCollector() external returns (address);
}
文件 24 的 45:IAxelarGateway.sol
pragma solidity ^0.8.0;
import { IGovernable } from './IGovernable.sol';
import { IImplementation } from './IImplementation.sol';
interface IAxelarGateway is IImplementation, IGovernable {
error NotSelf();
error InvalidCodeHash();
error SetupFailed();
error InvalidAuthModule();
error InvalidTokenDeployer();
error InvalidAmount();
error InvalidChainId();
error InvalidCommands();
error TokenDoesNotExist(string symbol);
error TokenAlreadyExists(string symbol);
error TokenDeployFailed(string symbol);
error TokenContractDoesNotExist(address token);
error BurnFailed(string symbol);
error MintFailed(string symbol);
error InvalidSetMintLimitsParams();
error ExceedMintLimit(string symbol);
event TokenSent(
address indexed sender,
string destinationChain,
string destinationAddress,
string symbol,
uint256 amount
);
event ContractCall(
address indexed sender,
string destinationChain,
string destinationContractAddress,
bytes32 indexed payloadHash,
bytes payload
);
event ContractCallWithToken(
address indexed sender,
string destinationChain,
string destinationContractAddress,
bytes32 indexed payloadHash,
bytes payload,
string symbol,
uint256 amount
);
event Executed(bytes32 indexed commandId);
event TokenDeployed(string symbol, address tokenAddresses);
event ContractCallApproved(
bytes32 indexed commandId,
string sourceChain,
string sourceAddress,
address indexed contractAddress,
bytes32 indexed payloadHash,
bytes32 sourceTxHash,
uint256 sourceEventIndex
);
event ContractCallApprovedWithMint(
bytes32 indexed commandId,
string sourceChain,
string sourceAddress,
address indexed contractAddress,
bytes32 indexed payloadHash,
string symbol,
uint256 amount,
bytes32 sourceTxHash,
uint256 sourceEventIndex
);
event ContractCallExecuted(bytes32 indexed commandId);
event TokenMintLimitUpdated(string symbol, uint256 limit);
event OperatorshipTransferred(bytes newOperatorsData);
event Upgraded(address indexed implementation);
function sendToken(
string calldata destinationChain,
string calldata destinationAddress,
string calldata symbol,
uint256 amount
) external;
function callContract(
string calldata destinationChain,
string calldata contractAddress,
bytes calldata payload
) external;
function callContractWithToken(
string calldata destinationChain,
string calldata contractAddress,
bytes calldata payload,
string calldata symbol,
uint256 amount
) external;
function isContractCallApproved(
bytes32 commandId,
string calldata sourceChain,
string calldata sourceAddress,
address contractAddress,
bytes32 payloadHash
) external view returns (bool);
function isContractCallAndMintApproved(
bytes32 commandId,
string calldata sourceChain,
string calldata sourceAddress,
address contractAddress,
bytes32 payloadHash,
string calldata symbol,
uint256 amount
) external view returns (bool);
function validateContractCall(
bytes32 commandId,
string calldata sourceChain,
string calldata sourceAddress,
bytes32 payloadHash
) external returns (bool);
function validateContractCallAndMint(
bytes32 commandId,
string calldata sourceChain,
string calldata sourceAddress,
bytes32 payloadHash,
string calldata symbol,
uint256 amount
) external returns (bool);
function authModule() external view returns (address);
function tokenDeployer() external view returns (address);
function tokenMintLimit(string memory symbol) external view returns (uint256);
function tokenMintAmount(string memory symbol) external view returns (uint256);
function allTokensFrozen() external view returns (bool);
function implementation() external view returns (address);
function tokenAddresses(string memory symbol) external view returns (address);
function tokenFrozen(string memory symbol) external view returns (bool);
function isCommandExecuted(bytes32 commandId) external view returns (bool);
function setTokenMintLimits(string[] calldata symbols, uint256[] calldata limits) external;
function upgrade(
address newImplementation,
bytes32 newImplementationCodeHash,
bytes calldata setupParams
) external;
function execute(bytes calldata input) external;
}
文件 25 的 45:ICallerBase.sol
pragma solidity 0.8.21;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "../types/AddressWithChain.sol";
interface ICallerBase {
event CrosschainSend(bytes32 indexed projectIdentifier, AddressWithChain destination, bytes additionalData);
event CrosschainReceive(bytes32 indexed projectIdentifier, AddressWithChain source, bytes additionalData);
}
文件 26 的 45:IContractIdentifier.sol
pragma solidity ^0.8.0;
interface IContractIdentifier {
function contractId() external pure returns (bytes32);
}
文件 27 的 45:IERC1155.sol
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
interface IERC1155 is IERC165 {
event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);
event TransferBatch(
address indexed operator,
address indexed from,
address indexed to,
uint256[] ids,
uint256[] values
);
event ApprovalForAll(address indexed account, address indexed operator, bool approved);
event URI(string value, uint256 indexed id);
function balanceOf(address account, uint256 id) external view returns (uint256);
function balanceOfBatch(
address[] calldata accounts,
uint256[] calldata ids
) external view returns (uint256[] memory);
function setApprovalForAll(address operator, bool approved) external;
function isApprovedForAll(address account, address operator) external view returns (bool);
function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;
function safeBatchTransferFrom(
address from,
address to,
uint256[] calldata ids,
uint256[] calldata amounts,
bytes calldata data
) external;
}
文件 28 的 45:IERC1155Receiver.sol
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
interface IERC1155Receiver is IERC165 {
function onERC1155Received(
address operator,
address from,
uint256 id,
uint256 value,
bytes calldata data
) external returns (bytes4);
function onERC1155BatchReceived(
address operator,
address from,
uint256[] calldata ids,
uint256[] calldata values,
bytes calldata data
) external returns (bytes4);
}
文件 29 的 45:IERC165.sol
pragma solidity ^0.8.0;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 30 的 45:IERC20.sol
pragma solidity ^0.8.0;
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address from, address to, uint256 amount) external returns (bool);
}
文件 31 的 45:IERC20Permit.sol
pragma solidity ^0.8.0;
interface IERC20Permit {
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
function nonces(address owner) external view returns (uint256);
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
文件 32 的 45:IERC721.sol
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
interface IERC721 is IERC165 {
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
function balanceOf(address owner) external view returns (uint256 balance);
function ownerOf(uint256 tokenId) external view returns (address owner);
function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;
function safeTransferFrom(address from, address to, uint256 tokenId) external;
function transferFrom(address from, address to, uint256 tokenId) external;
function approve(address to, uint256 tokenId) external;
function setApprovalForAll(address operator, bool approved) external;
function getApproved(uint256 tokenId) external view returns (address operator);
function isApprovedForAll(address owner, address operator) external view returns (bool);
}
文件 33 的 45:IERC721Receiver.sol
pragma solidity ^0.8.0;
interface IERC721Receiver {
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}
文件 34 的 45:IEeseeAccessManager.sol
pragma solidity 0.8.21;
interface IEeseeAccessManager {
event RoleGranted(bytes32 indexed role, address indexed account);
event RoleRevoked(bytes32 indexed role, address indexed account);
error CallerNotAdmin();
function hasRole(bytes32 role, address account) external view returns (bool);
function ADMIN_ROLE() external view returns (bytes32);
function grantRole(bytes32 role, address account) external;
function revokeRole(bytes32 role, address account) external;
}
文件 35 的 45:IEeseeAssetSpoke.sol
pragma solidity 0.8.21;
import "../types/Call.sol";
import "../types/AddressWithChain.sol";
interface IEeseeAssetSpoke {
function eeseeAssetHub() external view returns (bytes memory chainSelector, address _address);
function assetsStorage(bytes32) external view returns (
address token,
uint256 tokenID,
uint256 amount,
AssetType assetType,
bytes memory data
);
event Wrap(
Asset asset,
bytes32 indexed assetHash,
address indexed sender
);
event Unwrap(
Asset asset,
bytes32 indexed assetHash,
address indexed recipient
);
function wrap(
Asset[] calldata assets,
Call[] calldata crosschainCalls,
address fallbackRecipient,
bytes calldata additionalData
) external payable returns(uint256 gasPaid);
function unstuck(bytes32 stuckAssetHash, address recipient) external returns(Asset memory asset);
function getTokenIdL2(Asset calldata asset) external view returns (uint256);
function getTokenIdL2(bytes32 assetHash) external view returns (uint256);
function getAssetHash(Asset calldata asset) external pure returns (bytes32);
}
文件 36 的 45:IGovernable.sol
pragma solidity ^0.8.0;
interface IGovernable {
error NotGovernance();
error NotMintLimiter();
error InvalidGovernance();
error InvalidMintLimiter();
event GovernanceTransferred(address indexed previousGovernance, address indexed newGovernance);
event MintLimiterTransferred(address indexed previousGovernance, address indexed newGovernance);
function governance() external view returns (address);
function mintLimiter() external view returns (address);
function transferGovernance(address newGovernance) external;
function transferMintLimiter(address newGovernance) external;
}
文件 37 的 45:IImplementation.sol
pragma solidity ^0.8.0;
import { IContractIdentifier } from './IContractIdentifier.sol';
interface IImplementation is IContractIdentifier {
error NotProxy();
function setup(bytes calldata data) external;
}
文件 38 的 45:IOwnable.sol
pragma solidity ^0.8.0;
interface IOwnable {
error NotOwner();
error InvalidOwner();
error InvalidOwnerAddress();
event OwnershipTransferStarted(address indexed newOwner);
event OwnershipTransferred(address indexed newOwner);
function owner() external view returns (address);
function pendingOwner() external view returns (address);
function transferOwnership(address newOwner) external;
function proposeOwnership(address newOwner) external;
function acceptOwnership() external;
}
文件 39 的 45:IRoyaltyEngineV1.sol
pragma solidity 0.8.21;
import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
interface IRoyaltyEngineV1 is IERC165 {
function getRoyalty(address tokenAddress, uint256 tokenId, uint256 value)
external
returns (address payable[] memory recipients, uint256[] memory amounts);
function getRoyaltyView(address tokenAddress, uint256 tokenId, uint256 value)
external
view
returns (address payable[] memory recipients, uint256[] memory amounts);
}
文件 40 的 45:IUpgradable.sol
pragma solidity ^0.8.0;
import { IOwnable } from './IOwnable.sol';
import { IImplementation } from './IImplementation.sol';
interface IUpgradable is IOwnable, IImplementation {
error InvalidCodeHash();
error InvalidImplementation();
error SetupFailed();
event Upgraded(address indexed newImplementation);
function implementation() external view returns (address);
function upgrade(
address newImplementation,
bytes32 newImplementationCodeHash,
bytes calldata params
) external;
}
文件 41 的 45:Math.sol
pragma solidity ^0.8.0;
library Math {
enum Rounding {
Down,
Up,
Zero
}
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
function average(uint256 a, uint256 b) internal pure returns (uint256) {
return (a & b) + (a ^ b) / 2;
}
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
return a == 0 ? 0 : (a - 1) / b + 1;
}
function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
unchecked {
uint256 prod0;
uint256 prod1;
assembly {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
if (prod1 == 0) {
return prod0 / denominator;
}
require(denominator > prod1, "Math: mulDiv overflow");
uint256 remainder;
assembly {
remainder := mulmod(x, y, denominator)
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
uint256 twos = denominator & (~denominator + 1);
assembly {
denominator := div(denominator, twos)
prod0 := div(prod0, twos)
twos := add(div(sub(0, twos), twos), 1)
}
prod0 |= prod1 * twos;
uint256 inverse = (3 * denominator) ^ 2;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
result = prod0 * inverse;
return result;
}
}
function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 result = 1 << (log2(a) >> 1);
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
}
}
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
}
}
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10 ** 64) {
value /= 10 ** 64;
result += 64;
}
if (value >= 10 ** 32) {
value /= 10 ** 32;
result += 32;
}
if (value >= 10 ** 16) {
value /= 10 ** 16;
result += 16;
}
if (value >= 10 ** 8) {
value /= 10 ** 8;
result += 8;
}
if (value >= 10 ** 4) {
value /= 10 ** 4;
result += 4;
}
if (value >= 10 ** 2) {
value /= 10 ** 2;
result += 2;
}
if (value >= 10 ** 1) {
result += 1;
}
}
return result;
}
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);
}
}
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);
}
}
}
文件 42 的 45:Pausable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Pausable is Context {
event Paused(address account);
event Unpaused(address account);
bool private _paused;
constructor() {
_paused = false;
}
modifier whenNotPaused() {
_requireNotPaused();
_;
}
modifier whenPaused() {
_requirePaused();
_;
}
function paused() public view virtual returns (bool) {
return _paused;
}
function _requireNotPaused() internal view virtual {
require(!paused(), "Pausable: paused");
}
function _requirePaused() internal view virtual {
require(paused(), "Pausable: not paused");
}
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}
文件 43 的 45:SafeERC20.sol
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../extensions/IERC20Permit.sol";
import "../../../utils/Address.sol";
library SafeERC20 {
using Address for address;
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
function safeApprove(IERC20 token, address spender, uint256 value) internal {
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));
}
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));
}
}
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));
_callOptionalReturn(token, approvalCall);
}
}
function safePermit(
IERC20Permit token,
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
uint256 nonceBefore = token.nonces(owner);
token.permit(owner, spender, value, deadline, v, r, s);
uint256 nonceAfter = token.nonces(owner);
require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
}
function _callOptionalReturn(IERC20 token, bytes memory data) private {
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
(bool success, bytes memory returndata) = address(token).call(data);
return
success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));
}
}
文件 44 的 45:SignedMath.sol
pragma solidity ^0.8.0;
library SignedMath {
function max(int256 a, int256 b) internal pure returns (int256) {
return a > b ? a : b;
}
function min(int256 a, int256 b) internal pure returns (int256) {
return a < b ? a : b;
}
function average(int256 a, int256 b) internal pure returns (int256) {
int256 x = (a & b) + ((a ^ b) >> 1);
return x + (int256(uint256(x) >> 255) & (a ^ b));
}
function abs(int256 n) internal pure returns (uint256) {
unchecked {
return uint256(n >= 0 ? n : -n);
}
}
}
文件 45 的 45:Strings.sol
pragma solidity ^0.8.0;
import "./math/Math.sol";
import "./math/SignedMath.sol";
library Strings {
bytes16 private constant _SYMBOLS = "0123456789abcdef";
uint8 private constant _ADDRESS_LENGTH = 20;
function toString(uint256 value) internal pure returns (string memory) {
unchecked {
uint256 length = Math.log10(value) + 1;
string memory buffer = new string(length);
uint256 ptr;
assembly {
ptr := add(buffer, add(32, length))
}
while (true) {
ptr--;
assembly {
mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
}
value /= 10;
if (value == 0) break;
}
return buffer;
}
}
function toString(int256 value) internal pure returns (string memory) {
return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value))));
}
function toHexString(uint256 value) internal pure returns (string memory) {
unchecked {
return toHexString(value, Math.log256(value) + 1);
}
}
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
function toHexString(address addr) internal pure returns (string memory) {
return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
}
function equal(string memory a, string memory b) internal pure returns (bool) {
return keccak256(bytes(a)) == keccak256(bytes(b));
}
}
{
"compilationTarget": {
"contracts/periphery/crosschain/spoke/EeseeAssetSpokeAxelar.sol": "EeseeAssetSpokeAxelar"
},
"evmVersion": "shanghai",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 20000
},
"remappings": []
}
[{"inputs":[{"internalType":"contract IEeseeAccessManager","name":"_accessManager","type":"address"},{"internalType":"bytes","name":"_currentChainSelector","type":"bytes"},{"components":[{"internalType":"bytes","name":"chainSelector","type":"bytes"},{"internalType":"address","name":"_address","type":"address"}],"internalType":"struct AddressWithChain","name":"_eeseeAssetHub","type":"tuple"},{"internalType":"contract IRoyaltyEngineV1","name":"_royaltyEngine","type":"address"},{"internalType":"contract IAxelarGateway","name":"_gateway","type":"address"},{"internalType":"contract IAxelarGasService","name":"_gasService","type":"address"},{"internalType":"address","name":"trustedForwarder","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"CallerNotAuthorized","type":"error"},{"inputs":[],"name":"InsufficientValue","type":"error"},{"inputs":[],"name":"InvalidAccessManager","type":"error"},{"inputs":[],"name":"InvalidAddressString","type":"error"},{"inputs":[],"name":"InvalidAmount","type":"error"},{"inputs":[],"name":"InvalidAsset","type":"error"},{"inputs":[],"name":"InvalidAssetsLength","type":"error"},{"inputs":[],"name":"InvalidConstructor","type":"error"},{"inputs":[],"name":"InvalidGasService","type":"error"},{"inputs":[],"name":"InvalidGateway","type":"error"},{"inputs":[],"name":"InvalidInterface","type":"error"},{"inputs":[],"name":"InvalidRecipient","type":"error"},{"inputs":[],"name":"InvalidSender","type":"error"},{"inputs":[],"name":"InvalidToken","type":"error"},{"inputs":[],"name":"InvalidTokenID","type":"error"},{"inputs":[],"name":"NoAssetsStuck","type":"error"},{"inputs":[],"name":"NotApprovedByGateway","type":"error"},{"inputs":[],"name":"OnlySelf","type":"error"},{"inputs":[],"name":"TransferNotSuccessful","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"projectIdentifier","type":"bytes32"},{"components":[{"internalType":"bytes","name":"chainSelector","type":"bytes"},{"internalType":"address","name":"_address","type":"address"}],"indexed":false,"internalType":"struct AddressWithChain","name":"source","type":"tuple"},{"indexed":false,"internalType":"bytes","name":"additionalData","type":"bytes"}],"name":"CrosschainReceive","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"projectIdentifier","type":"bytes32"},{"components":[{"internalType":"bytes","name":"chainSelector","type":"bytes"},{"internalType":"address","name":"_address","type":"address"}],"indexed":false,"internalType":"struct AddressWithChain","name":"destination","type":"tuple"},{"indexed":false,"internalType":"bytes","name":"additionalData","type":"bytes"}],"name":"CrosschainSend","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"tokenID","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"enum AssetType","name":"assetType","type":"uint8"},{"internalType":"bytes","name":"data","type":"bytes"}],"indexed":false,"internalType":"struct Asset","name":"asset","type":"tuple"},{"indexed":true,"internalType":"bytes32","name":"assetHash","type":"bytes32"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"bytes","name":"err","type":"bytes"}],"name":"Stuck","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"tokenID","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"enum AssetType","name":"assetType","type":"uint8"},{"internalType":"bytes","name":"data","type":"bytes"}],"indexed":false,"internalType":"struct Asset","name":"asset","type":"tuple"},{"indexed":true,"internalType":"bytes32","name":"assetHash","type":"bytes32"},{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"}],"name":"Unstuck","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"tokenID","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"enum AssetType","name":"assetType","type":"uint8"},{"internalType":"bytes","name":"data","type":"bytes"}],"indexed":false,"internalType":"struct Asset","name":"asset","type":"tuple"},{"indexed":true,"internalType":"bytes32","name":"assetHash","type":"bytes32"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"}],"name":"Unwrap","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"tokenID","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"enum AssetType","name":"assetType","type":"uint8"},{"internalType":"bytes","name":"data","type":"bytes"}],"indexed":false,"internalType":"struct Asset","name":"asset","type":"tuple"},{"indexed":true,"internalType":"bytes32","name":"assetHash","type":"bytes32"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"Wrap","type":"event"},{"inputs":[],"name":"AXELAR_CALLER_IDENTIFIER","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"assetHash","type":"bytes32"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"_transferAssetTo","outputs":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"tokenID","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"enum AssetType","name":"assetType","type":"uint8"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct Asset","name":"asset","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"accessManager","outputs":[{"internalType":"contract IEeseeAccessManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"assetsStorage","outputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"tokenID","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"enum AssetType","name":"assetType","type":"uint8"},{"internalType":"bytes","name":"data","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"eeseeAssetHub","outputs":[{"internalType":"bytes","name":"chainSelector","type":"bytes"},{"internalType":"address","name":"_address","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"eeseeSpoke","outputs":[{"internalType":"bytes","name":"chainSelector","type":"bytes"},{"internalType":"address","name":"_address","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"commandId","type":"bytes32"},{"internalType":"string","name":"sourceChain","type":"string"},{"internalType":"string","name":"sourceAddress","type":"string"},{"internalType":"bytes","name":"payload","type":"bytes"}],"name":"execute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"gasService","outputs":[{"internalType":"contract IAxelarGasService","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gateway","outputs":[{"internalType":"contract IAxelarGateway","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"tokenID","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"enum AssetType","name":"assetType","type":"uint8"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct Asset","name":"asset","type":"tuple"}],"name":"getAssetHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"assetHash","type":"bytes32"}],"name":"getTokenIdL2","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"tokenID","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"enum AssetType","name":"assetType","type":"uint8"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct Asset","name":"asset","type":"tuple"}],"name":"getTokenIdL2","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"forwarder","type":"address"}],"name":"isTrustedForwarder","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155BatchReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"stuckAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"stuckAssetHash","type":"bytes32"},{"internalType":"address","name":"recipient","type":"address"}],"name":"unstuck","outputs":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"tokenID","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"enum AssetType","name":"assetType","type":"uint8"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct Asset","name":"asset","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"tokenID","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"enum AssetType","name":"assetType","type":"uint8"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct Asset[]","name":"assets","type":"tuple[]"},{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"bytes","name":"callData","type":"bytes"}],"internalType":"struct Call[]","name":"crosschainCalls","type":"tuple[]"},{"internalType":"address","name":"fallbackRecipient","type":"address"},{"internalType":"bytes","name":"additionalData","type":"bytes"}],"name":"wrap","outputs":[{"internalType":"uint256","name":"gasPaid","type":"uint256"}],"stateMutability":"payable","type":"function"}]