编译器
0.8.10+commit.fc410830
文件 1 的 6:Base.sol
pragma solidity ^0.8.0;
import "./Storage.sol";
import "./Events.sol";
import "./Proxy.sol";
abstract contract Base is Storage, Events {
function _createProxy(uint proxyModuleId) internal returns (address) {
require(proxyModuleId != 0, "e/create-proxy/invalid-module");
require(proxyModuleId <= MAX_EXTERNAL_MODULEID, "e/create-proxy/internal-module");
if (proxyLookup[proxyModuleId] != address(0)) return proxyLookup[proxyModuleId];
address proxyAddr = address(new Proxy());
if (proxyModuleId <= MAX_EXTERNAL_SINGLE_PROXY_MODULEID) proxyLookup[proxyModuleId] = proxyAddr;
trustedSenders[proxyAddr] = TrustedSenderInfo({ moduleId: uint32(proxyModuleId), moduleImpl: address(0) });
emit ProxyCreated(proxyAddr, proxyModuleId);
return proxyAddr;
}
function callInternalModule(uint moduleId, bytes memory input) internal returns (bytes memory) {
(bool success, bytes memory result) = moduleLookup[moduleId].delegatecall(input);
if (!success) revertBytes(result);
return result;
}
modifier nonReentrant() {
require(reentrancyLock == REENTRANCYLOCK__UNLOCKED, "e/reentrancy");
reentrancyLock = REENTRANCYLOCK__LOCKED;
_;
reentrancyLock = REENTRANCYLOCK__UNLOCKED;
}
modifier reentrantOK() {
_;
}
modifier FREEMEM() {
uint origFreeMemPtr;
assembly {
origFreeMemPtr := mload(0x40)
}
_;
assembly {
mstore(0x40, origFreeMemPtr)
}
}
function revertBytes(bytes memory errMsg) internal pure {
if (errMsg.length > 0) {
assembly {
revert(add(32, errMsg), mload(errMsg))
}
}
revert("e/empty-error");
}
}
文件 2 的 6:Constants.sol
pragma solidity ^0.8.0;
abstract contract Constants {
uint internal constant SECONDS_PER_YEAR = 365.2425 * 86400;
uint internal constant MAX_SANE_AMOUNT = type(uint112).max;
uint internal constant MAX_SANE_SMALL_AMOUNT = type(uint96).max;
uint internal constant MAX_SANE_DEBT_AMOUNT = type(uint144).max;
uint internal constant INTERNAL_DEBT_PRECISION = 1e9;
uint internal constant MAX_ENTERED_MARKETS = 10;
uint internal constant MAX_POSSIBLE_ENTERED_MARKETS = 2**32;
uint internal constant CONFIG_FACTOR_SCALE = 4_000_000_000;
uint internal constant RESERVE_FEE_SCALE = 4_000_000_000;
uint32 internal constant DEFAULT_RESERVE_FEE = uint32(0.23 * 4_000_000_000);
uint internal constant INITIAL_INTEREST_ACCUMULATOR = 1e27;
uint internal constant AVERAGE_LIQUIDITY_PERIOD = 24 * 60 * 60;
uint16 internal constant MIN_UNISWAP3_OBSERVATION_CARDINALITY = 10;
uint24 internal constant DEFAULT_TWAP_WINDOW_SECONDS = 30 * 60;
uint32 internal constant DEFAULT_BORROW_FACTOR = uint32(0.28 * 4_000_000_000);
uint internal constant REENTRANCYLOCK__UNLOCKED = 1;
uint internal constant REENTRANCYLOCK__LOCKED = 2;
uint8 internal constant DEFERLIQUIDITY__NONE = 0;
uint8 internal constant DEFERLIQUIDITY__CLEAN = 1;
uint8 internal constant DEFERLIQUIDITY__DIRTY = 2;
uint16 internal constant PRICINGTYPE__PEGGED = 1;
uint16 internal constant PRICINGTYPE__UNISWAP3_TWAP = 2;
uint16 internal constant PRICINGTYPE__FORWARDED = 3;
uint internal constant MODULEID__INSTALLER = 1;
uint internal constant MODULEID__MARKETS = 2;
uint internal constant MODULEID__LIQUIDATION = 3;
uint internal constant MODULEID__GOVERNANCE = 4;
uint internal constant MODULEID__EXEC = 5;
uint internal constant MODULEID__SWAP = 6;
uint internal constant MAX_EXTERNAL_SINGLE_PROXY_MODULEID = 499_999;
uint internal constant MODULEID__ETOKEN = 500_000;
uint internal constant MODULEID__DTOKEN = 500_001;
uint internal constant MAX_EXTERNAL_MODULEID = 999_999;
uint internal constant MODULEID__RISK_MANAGER = 1_000_000;
uint internal constant MODULEID__IRM_DEFAULT = 2_000_000;
uint internal constant MODULEID__IRM_ZERO = 2_000_001;
uint internal constant MODULEID__IRM_FIXED = 2_000_002;
uint internal constant MODULEID__IRM_LINEAR = 2_000_100;
uint internal constant MODULEID__IRM_CLASS__STABLE = 2_000_500;
uint internal constant MODULEID__IRM_CLASS__MAJOR = 2_000_501;
uint internal constant MODULEID__IRM_CLASS__MIDCAP = 2_000_502;
uint internal constant SWAP_TYPE__UNI_EXACT_INPUT_SINGLE = 1;
uint internal constant SWAP_TYPE__UNI_EXACT_INPUT = 2;
uint internal constant SWAP_TYPE__UNI_EXACT_OUTPUT_SINGLE = 3;
uint internal constant SWAP_TYPE__UNI_EXACT_OUTPUT = 4;
uint internal constant SWAP_TYPE__1INCH = 5;
}
文件 3 的 6:Euler.sol
pragma solidity ^0.8.0;
import "./Base.sol";
contract Euler is Base {
constructor(address admin, address installerModule) {
emit Genesis();
reentrancyLock = REENTRANCYLOCK__UNLOCKED;
upgradeAdmin = admin;
governorAdmin = admin;
moduleLookup[MODULEID__INSTALLER] = installerModule;
address installerProxy = _createProxy(MODULEID__INSTALLER);
trustedSenders[installerProxy].moduleImpl = installerModule;
}
string public constant name = "Euler Protocol";
function moduleIdToImplementation(uint moduleId) external view returns (address) {
return moduleLookup[moduleId];
}
function moduleIdToProxy(uint moduleId) external view returns (address) {
return proxyLookup[moduleId];
}
function dispatch() external {
uint32 moduleId = trustedSenders[msg.sender].moduleId;
address moduleImpl = trustedSenders[msg.sender].moduleImpl;
require(moduleId != 0, "e/sender-not-trusted");
if (moduleImpl == address(0)) moduleImpl = moduleLookup[moduleId];
uint msgDataLength = msg.data.length;
require(msgDataLength >= (4 + 4 + 20), "e/input-too-short");
assembly {
let payloadSize := sub(calldatasize(), 4)
calldatacopy(0, 4, payloadSize)
mstore(payloadSize, shl(96, caller()))
let result := delegatecall(gas(), moduleImpl, 0, add(payloadSize, 20), 0, 0)
returndatacopy(0, 0, returndatasize())
switch result
case 0 { revert(0, returndatasize()) }
default { return(0, returndatasize()) }
}
}
}
文件 4 的 6:Events.sol
pragma solidity ^0.8.0;
import "./Storage.sol";
abstract contract Events {
event Genesis();
event ProxyCreated(address indexed proxy, uint moduleId);
event MarketActivated(address indexed underlying, address indexed eToken, address indexed dToken);
event PTokenActivated(address indexed underlying, address indexed pToken);
event EnterMarket(address indexed underlying, address indexed account);
event ExitMarket(address indexed underlying, address indexed account);
event Deposit(address indexed underlying, address indexed account, uint amount);
event Withdraw(address indexed underlying, address indexed account, uint amount);
event Borrow(address indexed underlying, address indexed account, uint amount);
event Repay(address indexed underlying, address indexed account, uint amount);
event Liquidation(address indexed liquidator, address indexed violator, address indexed underlying, address collateral, uint repay, uint yield, uint healthScore, uint baseDiscount, uint discount);
event TrackAverageLiquidity(address indexed account);
event UnTrackAverageLiquidity(address indexed account);
event DelegateAverageLiquidity(address indexed account, address indexed delegate);
event PTokenWrap(address indexed underlying, address indexed account, uint amount);
event PTokenUnWrap(address indexed underlying, address indexed account, uint amount);
event AssetStatus(address indexed underlying, uint totalBalances, uint totalBorrows, uint96 reserveBalance, uint poolSize, uint interestAccumulator, int96 interestRate, uint timestamp);
event RequestDeposit(address indexed account, uint amount);
event RequestWithdraw(address indexed account, uint amount);
event RequestMint(address indexed account, uint amount);
event RequestBurn(address indexed account, uint amount);
event RequestTransferEToken(address indexed from, address indexed to, uint amount);
event RequestBorrow(address indexed account, uint amount);
event RequestRepay(address indexed account, uint amount);
event RequestTransferDToken(address indexed from, address indexed to, uint amount);
event RequestLiquidate(address indexed liquidator, address indexed violator, address indexed underlying, address collateral, uint repay, uint minYield);
event InstallerSetUpgradeAdmin(address indexed newUpgradeAdmin);
event InstallerSetGovernorAdmin(address indexed newGovernorAdmin);
event InstallerInstallModule(uint indexed moduleId, address indexed moduleImpl, bytes32 moduleGitCommit);
event GovSetAssetConfig(address indexed underlying, Storage.AssetConfig newConfig);
event GovSetIRM(address indexed underlying, uint interestRateModel, bytes resetParams);
event GovSetPricingConfig(address indexed underlying, uint16 newPricingType, uint32 newPricingParameter);
event GovSetReserveFee(address indexed underlying, uint32 newReserveFee);
event GovConvertReserves(address indexed underlying, address indexed recipient, uint amount);
event RequestSwap(address indexed accountIn, address indexed accountOut, address indexed underlyingIn, address underlyingOut, uint amount, uint swapType);
}
文件 5 的 6:Proxy.sol
pragma solidity ^0.8.0;
contract Proxy {
address immutable creator;
constructor() {
creator = msg.sender;
}
fallback() external {
address creator_ = creator;
if (msg.sender == creator_) {
assembly {
mstore(0, 0)
calldatacopy(31, 0, calldatasize())
switch mload(0)
case 0 { log0(32, sub(calldatasize(), 1)) }
case 1 { log1(64, sub(calldatasize(), 33), mload(32)) }
case 2 { log2(96, sub(calldatasize(), 65), mload(32), mload(64)) }
case 3 { log3(128, sub(calldatasize(), 97), mload(32), mload(64), mload(96)) }
case 4 { log4(160, sub(calldatasize(), 129), mload(32), mload(64), mload(96), mload(128)) }
default { revert(0, 0) }
return(0, 0)
}
} else {
assembly {
mstore(0, 0xe9c4a3ac00000000000000000000000000000000000000000000000000000000)
calldatacopy(4, 0, calldatasize())
mstore(add(4, calldatasize()), shl(96, caller()))
let result := call(gas(), creator_, 0, 0, add(24, calldatasize()), 0, 0)
returndatacopy(0, 0, returndatasize())
switch result
case 0 { revert(0, returndatasize()) }
default { return(0, returndatasize()) }
}
}
}
}
文件 6 的 6:Storage.sol
pragma solidity ^0.8.0;
import "./Constants.sol";
abstract contract Storage is Constants {
uint reentrancyLock;
address upgradeAdmin;
address governorAdmin;
mapping(uint => address) moduleLookup;
mapping(uint => address) proxyLookup;
struct TrustedSenderInfo {
uint32 moduleId;
address moduleImpl;
}
mapping(address => TrustedSenderInfo) trustedSenders;
struct AccountStorage {
uint8 deferLiquidityStatus;
uint40 lastAverageLiquidityUpdate;
uint32 numMarketsEntered;
address firstMarketEntered;
uint averageLiquidity;
address averageLiquidityDelegate;
}
mapping(address => AccountStorage) accountLookup;
mapping(address => address[MAX_POSSIBLE_ENTERED_MARKETS]) marketsEntered;
struct AssetConfig {
address eTokenAddress;
bool borrowIsolated;
uint32 collateralFactor;
uint32 borrowFactor;
uint24 twapWindow;
}
struct UserAsset {
uint112 balance;
uint144 owed;
uint interestAccumulator;
}
struct AssetStorage {
uint40 lastInterestAccumulatorUpdate;
uint8 underlyingDecimals;
uint32 interestRateModel;
int96 interestRate;
uint32 reserveFee;
uint16 pricingType;
uint32 pricingParameters;
address underlying;
uint96 reserveBalance;
address dTokenAddress;
uint112 totalBalances;
uint144 totalBorrows;
uint interestAccumulator;
mapping(address => UserAsset) users;
mapping(address => mapping(address => uint)) eTokenAllowance;
mapping(address => mapping(address => uint)) dTokenAllowance;
}
mapping(address => AssetConfig) internal underlyingLookup;
mapping(address => AssetStorage) internal eTokenLookup;
mapping(address => address) internal dTokenLookup;
mapping(address => address) internal pTokenLookup;
mapping(address => address) internal reversePTokenLookup;
}
{
"compilationTarget": {
"contracts/Euler.sol": "Euler"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 1000000
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"admin","type":"address"},{"internalType":"address","name":"installerModule","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"underlying","type":"address"},{"indexed":false,"internalType":"uint256","name":"totalBalances","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalBorrows","type":"uint256"},{"indexed":false,"internalType":"uint96","name":"reserveBalance","type":"uint96"},{"indexed":false,"internalType":"uint256","name":"poolSize","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"interestAccumulator","type":"uint256"},{"indexed":false,"internalType":"int96","name":"interestRate","type":"int96"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"AssetStatus","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"underlying","type":"address"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Borrow","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"delegate","type":"address"}],"name":"DelegateAverageLiquidity","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"underlying","type":"address"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"underlying","type":"address"},{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"EnterMarket","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"underlying","type":"address"},{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"ExitMarket","type":"event"},{"anonymous":false,"inputs":[],"name":"Genesis","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"underlying","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"GovConvertReserves","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"underlying","type":"address"},{"components":[{"internalType":"address","name":"eTokenAddress","type":"address"},{"internalType":"bool","name":"borrowIsolated","type":"bool"},{"internalType":"uint32","name":"collateralFactor","type":"uint32"},{"internalType":"uint32","name":"borrowFactor","type":"uint32"},{"internalType":"uint24","name":"twapWindow","type":"uint24"}],"indexed":false,"internalType":"struct Storage.AssetConfig","name":"newConfig","type":"tuple"}],"name":"GovSetAssetConfig","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"underlying","type":"address"},{"indexed":false,"internalType":"uint256","name":"interestRateModel","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"resetParams","type":"bytes"}],"name":"GovSetIRM","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"underlying","type":"address"},{"indexed":false,"internalType":"uint16","name":"newPricingType","type":"uint16"},{"indexed":false,"internalType":"uint32","name":"newPricingParameter","type":"uint32"}],"name":"GovSetPricingConfig","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"underlying","type":"address"},{"indexed":false,"internalType":"uint32","name":"newReserveFee","type":"uint32"}],"name":"GovSetReserveFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"moduleId","type":"uint256"},{"indexed":true,"internalType":"address","name":"moduleImpl","type":"address"},{"indexed":false,"internalType":"bytes32","name":"moduleGitCommit","type":"bytes32"}],"name":"InstallerInstallModule","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newGovernorAdmin","type":"address"}],"name":"InstallerSetGovernorAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newUpgradeAdmin","type":"address"}],"name":"InstallerSetUpgradeAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"liquidator","type":"address"},{"indexed":true,"internalType":"address","name":"violator","type":"address"},{"indexed":true,"internalType":"address","name":"underlying","type":"address"},{"indexed":false,"internalType":"address","name":"collateral","type":"address"},{"indexed":false,"internalType":"uint256","name":"repay","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"yield","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"healthScore","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"baseDiscount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"discount","type":"uint256"}],"name":"Liquidation","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"underlying","type":"address"},{"indexed":true,"internalType":"address","name":"eToken","type":"address"},{"indexed":true,"internalType":"address","name":"dToken","type":"address"}],"name":"MarketActivated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"underlying","type":"address"},{"indexed":true,"internalType":"address","name":"pToken","type":"address"}],"name":"PTokenActivated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"underlying","type":"address"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PTokenUnWrap","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"underlying","type":"address"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PTokenWrap","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"proxy","type":"address"},{"indexed":false,"internalType":"uint256","name":"moduleId","type":"uint256"}],"name":"ProxyCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"underlying","type":"address"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Repay","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RequestBorrow","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RequestBurn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RequestDeposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"liquidator","type":"address"},{"indexed":true,"internalType":"address","name":"violator","type":"address"},{"indexed":true,"internalType":"address","name":"underlying","type":"address"},{"indexed":false,"internalType":"address","name":"collateral","type":"address"},{"indexed":false,"internalType":"uint256","name":"repay","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"minYield","type":"uint256"}],"name":"RequestLiquidate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RequestMint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RequestRepay","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"accountIn","type":"address"},{"indexed":true,"internalType":"address","name":"accountOut","type":"address"},{"indexed":true,"internalType":"address","name":"underlyingIn","type":"address"},{"indexed":false,"internalType":"address","name":"underlyingOut","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"swapType","type":"uint256"}],"name":"RequestSwap","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RequestTransferDToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RequestTransferEToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RequestWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"TrackAverageLiquidity","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"UnTrackAverageLiquidity","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"underlying","type":"address"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"dispatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"moduleId","type":"uint256"}],"name":"moduleIdToImplementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"moduleId","type":"uint256"}],"name":"moduleIdToProxy","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"}]