Source Code
Overview
ETH Balance
0 ETH
More Info
ContractCreator
Multichain Info
N/A
| Transaction Hash |
Method
|
Block
|
From
|
To
|
Amount
|
||||
|---|---|---|---|---|---|---|---|---|---|
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
To
|
Amount
|
||
|---|---|---|---|---|---|---|---|
| Has Permission | 2067664 | 6 hrs ago | 0 ETH | ||||
| Has Permission | 2067664 | 6 hrs ago | 0 ETH | ||||
| Has Permission | 2067664 | 6 hrs ago | 0 ETH | ||||
| Has Permission | 2067658 | 6 hrs ago | 0 ETH | ||||
| Has Permission | 2067658 | 6 hrs ago | 0 ETH | ||||
| Has Permission | 2067658 | 6 hrs ago | 0 ETH | ||||
| Has Permission | 2065466 | 14 hrs ago | 0 ETH | ||||
| Has Permission | 2065466 | 14 hrs ago | 0 ETH | ||||
| Has Permission | 2065466 | 14 hrs ago | 0 ETH | ||||
| Has Permission | 2065454 | 14 hrs ago | 0 ETH | ||||
| Has Permission | 2065454 | 14 hrs ago | 0 ETH | ||||
| Has Permission | 2065454 | 14 hrs ago | 0 ETH | ||||
| Has Permission | 2063249 | 22 hrs ago | 0 ETH | ||||
| Has Permission | 2063249 | 22 hrs ago | 0 ETH | ||||
| Has Permission | 2063249 | 22 hrs ago | 0 ETH | ||||
| Has Permission | 2063241 | 22 hrs ago | 0 ETH | ||||
| Has Permission | 2063241 | 22 hrs ago | 0 ETH | ||||
| Has Permission | 2063241 | 22 hrs ago | 0 ETH | ||||
| Has Permission | 2063070 | 23 hrs ago | 0 ETH | ||||
| Has Permission | 2061070 | 30 hrs ago | 0 ETH | ||||
| Has Permission | 2061067 | 30 hrs ago | 0 ETH | ||||
| Has Permission | 2061067 | 30 hrs ago | 0 ETH | ||||
| Has Permission | 2061067 | 30 hrs ago | 0 ETH | ||||
| Has Permission | 2061060 | 30 hrs ago | 0 ETH | ||||
| Has Permission | 2061060 | 30 hrs ago | 0 ETH |
Loading...
Loading
Loading...
Loading
Contract Name:
ACL
Compiler Version
v0.4.24+commit.e67f0147
Optimization Enabled:
Yes with 200 runs
Other Settings:
constantinople EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
pragma solidity 0.4.24;
import "../apps/AragonApp.sol";
import "../common/ConversionHelpers.sol";
import "../common/TimeHelpers.sol";
import "./ACLSyntaxSugar.sol";
import "./IACL.sol";
import "./IACLOracle.sol";
/* solium-disable function-order */
// Allow public initialize() to be first
contract ACL is IACL, TimeHelpers, AragonApp, ACLHelpers {
/* Hardcoded constants to save gas
bytes32 public constant CREATE_PERMISSIONS_ROLE = keccak256("CREATE_PERMISSIONS_ROLE");
*/
bytes32 public constant CREATE_PERMISSIONS_ROLE = 0x0b719b33c83b8e5d300c521cb8b54ae9bd933996a14bef8c2f4e0285d2d2400a;
enum Op { NONE, EQ, NEQ, GT, LT, GTE, LTE, RET, NOT, AND, OR, XOR, IF_ELSE } // op types
struct Param {
uint8 id;
uint8 op;
uint240 value; // even though value is an uint240 it can store addresses
// in the case of 32 byte hashes losing 2 bytes precision isn't a huge deal
// op and id take less than 1 byte each so it can be kept in 1 sstore
}
uint8 internal constant BLOCK_NUMBER_PARAM_ID = 200;
uint8 internal constant TIMESTAMP_PARAM_ID = 201;
// 202 is unused
uint8 internal constant ORACLE_PARAM_ID = 203;
uint8 internal constant LOGIC_OP_PARAM_ID = 204;
uint8 internal constant PARAM_VALUE_PARAM_ID = 205;
// TODO: Add execution times param type?
/* Hardcoded constant to save gas
bytes32 public constant EMPTY_PARAM_HASH = keccak256(uint256(0));
*/
bytes32 public constant EMPTY_PARAM_HASH = 0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563;
bytes32 public constant NO_PERMISSION = bytes32(0);
address public constant ANY_ENTITY = address(-1);
address public constant BURN_ENTITY = address(1); // address(0) is already used as "no permission manager"
string private constant ERROR_AUTH_INIT_KERNEL = "ACL_AUTH_INIT_KERNEL";
string private constant ERROR_AUTH_NO_MANAGER = "ACL_AUTH_NO_MANAGER";
string private constant ERROR_EXISTENT_MANAGER = "ACL_EXISTENT_MANAGER";
// Whether someone has a permission
mapping (bytes32 => bytes32) internal permissions; // permissions hash => params hash
mapping (bytes32 => Param[]) internal permissionParams; // params hash => params
// Who is the manager of a permission
mapping (bytes32 => address) internal permissionManager;
event SetPermission(address indexed entity, address indexed app, bytes32 indexed role, bool allowed);
event SetPermissionParams(address indexed entity, address indexed app, bytes32 indexed role, bytes32 paramsHash);
event ChangePermissionManager(address indexed app, bytes32 indexed role, address indexed manager);
modifier onlyPermissionManager(address _app, bytes32 _role) {
require(msg.sender == getPermissionManager(_app, _role), ERROR_AUTH_NO_MANAGER);
_;
}
modifier noPermissionManager(address _app, bytes32 _role) {
// only allow permission creation (or re-creation) when there is no manager
require(getPermissionManager(_app, _role) == address(0), ERROR_EXISTENT_MANAGER);
_;
}
/**
* @dev Initialize can only be called once. It saves the block number in which it was initialized.
* @notice Initialize an ACL instance and set `_permissionsCreator` as the entity that can create other permissions
* @param _permissionsCreator Entity that will be given permission over createPermission
*/
function initialize(address _permissionsCreator) public onlyInit {
initialized();
require(msg.sender == address(kernel()), ERROR_AUTH_INIT_KERNEL);
_createPermission(_permissionsCreator, this, CREATE_PERMISSIONS_ROLE, _permissionsCreator);
}
/**
* @dev Creates a permission that wasn't previously set and managed.
* If a created permission is removed it is possible to reset it with createPermission.
* This is the **ONLY** way to create permissions and set managers to permissions that don't
* have a manager.
* In terms of the ACL being initialized, this function implicitly protects all the other
* state-changing external functions, as they all require the sender to be a manager.
* @notice Create a new permission granting `_entity` the ability to perform actions requiring `_role` on `_app`, setting `_manager` as the permission's manager
* @param _entity Address of the whitelisted entity that will be able to perform the role
* @param _app Address of the app in which the role will be allowed (requires app to depend on kernel for ACL)
* @param _role Identifier for the group of actions in app given access to perform
* @param _manager Address of the entity that will be able to grant and revoke the permission further.
*/
function createPermission(address _entity, address _app, bytes32 _role, address _manager)
external
auth(CREATE_PERMISSIONS_ROLE)
noPermissionManager(_app, _role)
{
_createPermission(_entity, _app, _role, _manager);
}
/**
* @dev Grants permission if allowed. This requires `msg.sender` to be the permission manager
* @notice Grant `_entity` the ability to perform actions requiring `_role` on `_app`
* @param _entity Address of the whitelisted entity that will be able to perform the role
* @param _app Address of the app in which the role will be allowed (requires app to depend on kernel for ACL)
* @param _role Identifier for the group of actions in app given access to perform
*/
function grantPermission(address _entity, address _app, bytes32 _role)
external
{
grantPermissionP(_entity, _app, _role, new uint256[](0));
}
/**
* @dev Grants a permission with parameters if allowed. This requires `msg.sender` to be the permission manager
* @notice Grant `_entity` the ability to perform actions requiring `_role` on `_app`
* @param _entity Address of the whitelisted entity that will be able to perform the role
* @param _app Address of the app in which the role will be allowed (requires app to depend on kernel for ACL)
* @param _role Identifier for the group of actions in app given access to perform
* @param _params Permission parameters
*/
function grantPermissionP(address _entity, address _app, bytes32 _role, uint256[] _params)
public
onlyPermissionManager(_app, _role)
{
bytes32 paramsHash = _params.length > 0 ? _saveParams(_params) : EMPTY_PARAM_HASH;
_setPermission(_entity, _app, _role, paramsHash);
}
/**
* @dev Revokes permission if allowed. This requires `msg.sender` to be the the permission manager
* @notice Revoke from `_entity` the ability to perform actions requiring `_role` on `_app`
* @param _entity Address of the whitelisted entity to revoke access from
* @param _app Address of the app in which the role will be revoked
* @param _role Identifier for the group of actions in app being revoked
*/
function revokePermission(address _entity, address _app, bytes32 _role)
external
onlyPermissionManager(_app, _role)
{
_setPermission(_entity, _app, _role, NO_PERMISSION);
}
/**
* @notice Set `_newManager` as the manager of `_role` in `_app`
* @param _newManager Address for the new manager
* @param _app Address of the app in which the permission management is being transferred
* @param _role Identifier for the group of actions being transferred
*/
function setPermissionManager(address _newManager, address _app, bytes32 _role)
external
onlyPermissionManager(_app, _role)
{
_setPermissionManager(_newManager, _app, _role);
}
/**
* @notice Remove the manager of `_role` in `_app`
* @param _app Address of the app in which the permission is being unmanaged
* @param _role Identifier for the group of actions being unmanaged
*/
function removePermissionManager(address _app, bytes32 _role)
external
onlyPermissionManager(_app, _role)
{
_setPermissionManager(address(0), _app, _role);
}
/**
* @notice Burn non-existent `_role` in `_app`, so no modification can be made to it (grant, revoke, permission manager)
* @param _app Address of the app in which the permission is being burned
* @param _role Identifier for the group of actions being burned
*/
function createBurnedPermission(address _app, bytes32 _role)
external
auth(CREATE_PERMISSIONS_ROLE)
noPermissionManager(_app, _role)
{
_setPermissionManager(BURN_ENTITY, _app, _role);
}
/**
* @notice Burn `_role` in `_app`, so no modification can be made to it (grant, revoke, permission manager)
* @param _app Address of the app in which the permission is being burned
* @param _role Identifier for the group of actions being burned
*/
function burnPermissionManager(address _app, bytes32 _role)
external
onlyPermissionManager(_app, _role)
{
_setPermissionManager(BURN_ENTITY, _app, _role);
}
/**
* @notice Get parameters for permission array length
* @param _entity Address of the whitelisted entity that will be able to perform the role
* @param _app Address of the app
* @param _role Identifier for a group of actions in app
* @return Length of the array
*/
function getPermissionParamsLength(address _entity, address _app, bytes32 _role) external view returns (uint) {
return permissionParams[permissions[permissionHash(_entity, _app, _role)]].length;
}
/**
* @notice Get parameter for permission
* @param _entity Address of the whitelisted entity that will be able to perform the role
* @param _app Address of the app
* @param _role Identifier for a group of actions in app
* @param _index Index of parameter in the array
* @return Parameter (id, op, value)
*/
function getPermissionParam(address _entity, address _app, bytes32 _role, uint _index)
external
view
returns (uint8, uint8, uint240)
{
Param storage param = permissionParams[permissions[permissionHash(_entity, _app, _role)]][_index];
return (param.id, param.op, param.value);
}
/**
* @dev Get manager for permission
* @param _app Address of the app
* @param _role Identifier for a group of actions in app
* @return address of the manager for the permission
*/
function getPermissionManager(address _app, bytes32 _role) public view returns (address) {
return permissionManager[roleHash(_app, _role)];
}
/**
* @dev Function called by apps to check ACL on kernel or to check permission statu
* @param _who Sender of the original call
* @param _where Address of the app
* @param _where Identifier for a group of actions in app
* @param _how Permission parameters
* @return boolean indicating whether the ACL allows the role or not
*/
function hasPermission(address _who, address _where, bytes32 _what, bytes memory _how) public view returns (bool) {
return hasPermission(_who, _where, _what, ConversionHelpers.dangerouslyCastBytesToUintArray(_how));
}
function hasPermission(address _who, address _where, bytes32 _what, uint256[] memory _how) public view returns (bool) {
bytes32 whoParams = permissions[permissionHash(_who, _where, _what)];
if (whoParams != NO_PERMISSION && evalParams(whoParams, _who, _where, _what, _how)) {
return true;
}
bytes32 anyParams = permissions[permissionHash(ANY_ENTITY, _where, _what)];
if (anyParams != NO_PERMISSION && evalParams(anyParams, ANY_ENTITY, _where, _what, _how)) {
return true;
}
return false;
}
function hasPermission(address _who, address _where, bytes32 _what) public view returns (bool) {
uint256[] memory empty = new uint256[](0);
return hasPermission(_who, _where, _what, empty);
}
function evalParams(
bytes32 _paramsHash,
address _who,
address _where,
bytes32 _what,
uint256[] _how
) public view returns (bool)
{
if (_paramsHash == EMPTY_PARAM_HASH) {
return true;
}
return _evalParam(_paramsHash, 0, _who, _where, _what, _how);
}
/**
* @dev Internal createPermission for access inside the kernel (on instantiation)
*/
function _createPermission(address _entity, address _app, bytes32 _role, address _manager) internal {
_setPermission(_entity, _app, _role, EMPTY_PARAM_HASH);
_setPermissionManager(_manager, _app, _role);
}
/**
* @dev Internal function called to actually save the permission
*/
function _setPermission(address _entity, address _app, bytes32 _role, bytes32 _paramsHash) internal {
permissions[permissionHash(_entity, _app, _role)] = _paramsHash;
bool entityHasPermission = _paramsHash != NO_PERMISSION;
bool permissionHasParams = entityHasPermission && _paramsHash != EMPTY_PARAM_HASH;
emit SetPermission(_entity, _app, _role, entityHasPermission);
if (permissionHasParams) {
emit SetPermissionParams(_entity, _app, _role, _paramsHash);
}
}
function _saveParams(uint256[] _encodedParams) internal returns (bytes32) {
bytes32 paramHash = keccak256(abi.encodePacked(_encodedParams));
Param[] storage params = permissionParams[paramHash];
if (params.length == 0) { // params not saved before
for (uint256 i = 0; i < _encodedParams.length; i++) {
uint256 encodedParam = _encodedParams[i];
Param memory param = Param(decodeParamId(encodedParam), decodeParamOp(encodedParam), uint240(encodedParam));
params.push(param);
}
}
return paramHash;
}
function _evalParam(
bytes32 _paramsHash,
uint32 _paramId,
address _who,
address _where,
bytes32 _what,
uint256[] _how
) internal view returns (bool)
{
if (_paramId >= permissionParams[_paramsHash].length) {
return false; // out of bounds
}
Param memory param = permissionParams[_paramsHash][_paramId];
if (param.id == LOGIC_OP_PARAM_ID) {
return _evalLogic(param, _paramsHash, _who, _where, _what, _how);
}
uint256 value;
uint256 comparedTo = uint256(param.value);
// get value
if (param.id == ORACLE_PARAM_ID) {
value = checkOracle(IACLOracle(param.value), _who, _where, _what, _how) ? 1 : 0;
comparedTo = 1;
} else if (param.id == BLOCK_NUMBER_PARAM_ID) {
value = getBlockNumber();
} else if (param.id == TIMESTAMP_PARAM_ID) {
value = getTimestamp();
} else if (param.id == PARAM_VALUE_PARAM_ID) {
value = uint256(param.value);
} else {
if (param.id >= _how.length) {
return false;
}
value = uint256(uint240(_how[param.id])); // force lost precision
}
if (Op(param.op) == Op.RET) {
return uint256(value) > 0;
}
return compare(value, Op(param.op), comparedTo);
}
function _evalLogic(Param _param, bytes32 _paramsHash, address _who, address _where, bytes32 _what, uint256[] _how)
internal
view
returns (bool)
{
if (Op(_param.op) == Op.IF_ELSE) {
uint32 conditionParam;
uint32 successParam;
uint32 failureParam;
(conditionParam, successParam, failureParam) = decodeParamsList(uint256(_param.value));
bool result = _evalParam(_paramsHash, conditionParam, _who, _where, _what, _how);
return _evalParam(_paramsHash, result ? successParam : failureParam, _who, _where, _what, _how);
}
uint32 param1;
uint32 param2;
(param1, param2,) = decodeParamsList(uint256(_param.value));
bool r1 = _evalParam(_paramsHash, param1, _who, _where, _what, _how);
if (Op(_param.op) == Op.NOT) {
return !r1;
}
if (r1 && Op(_param.op) == Op.OR) {
return true;
}
if (!r1 && Op(_param.op) == Op.AND) {
return false;
}
bool r2 = _evalParam(_paramsHash, param2, _who, _where, _what, _how);
if (Op(_param.op) == Op.XOR) {
return r1 != r2;
}
return r2; // both or and and depend on result of r2 after checks
}
function compare(uint256 _a, Op _op, uint256 _b) internal pure returns (bool) {
if (_op == Op.EQ) return _a == _b; // solium-disable-line lbrace
if (_op == Op.NEQ) return _a != _b; // solium-disable-line lbrace
if (_op == Op.GT) return _a > _b; // solium-disable-line lbrace
if (_op == Op.LT) return _a < _b; // solium-disable-line lbrace
if (_op == Op.GTE) return _a >= _b; // solium-disable-line lbrace
if (_op == Op.LTE) return _a <= _b; // solium-disable-line lbrace
return false;
}
function checkOracle(IACLOracle _oracleAddr, address _who, address _where, bytes32 _what, uint256[] _how) internal view returns (bool) {
bytes4 sig = _oracleAddr.canPerform.selector;
// a raw call is required so we can return false if the call reverts, rather than reverting
bytes memory checkCalldata = abi.encodeWithSelector(sig, _who, _where, _what, _how);
bool ok;
assembly {
// send all available gas; if the oracle eats up all the gas, we will eventually revert
// note that we are currently guaranteed to still have some gas after the call from
// EIP-150's 63/64 gas forward rule
ok := staticcall(gas, _oracleAddr, add(checkCalldata, 0x20), mload(checkCalldata), 0, 0)
}
if (!ok) {
return false;
}
uint256 size;
assembly { size := returndatasize }
if (size != 32) {
return false;
}
bool result;
assembly {
let ptr := mload(0x40) // get next free memory ptr
returndatacopy(ptr, 0, size) // copy return from above `staticcall`
result := mload(ptr) // read data at ptr and set it to result
mstore(ptr, 0) // set pointer memory to 0 so it still is the next free ptr
}
return result;
}
/**
* @dev Internal function that sets management
*/
function _setPermissionManager(address _newManager, address _app, bytes32 _role) internal {
permissionManager[roleHash(_app, _role)] = _newManager;
emit ChangePermissionManager(_app, _role, _newManager);
}
function roleHash(address _where, bytes32 _what) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("ROLE", _where, _what));
}
function permissionHash(address _who, address _where, bytes32 _what) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("PERMISSION", _who, _where, _what));
}
}/*
* SPDX-License-Identifier: MIT
*/
pragma solidity ^0.4.24;
contract ACLSyntaxSugar {
function arr() internal pure returns (uint256[]) {
return new uint256[](0);
}
function arr(bytes32 _a) internal pure returns (uint256[] r) {
return arr(uint256(_a));
}
function arr(bytes32 _a, bytes32 _b) internal pure returns (uint256[] r) {
return arr(uint256(_a), uint256(_b));
}
function arr(address _a) internal pure returns (uint256[] r) {
return arr(uint256(_a));
}
function arr(address _a, address _b) internal pure returns (uint256[] r) {
return arr(uint256(_a), uint256(_b));
}
function arr(address _a, uint256 _b, uint256 _c) internal pure returns (uint256[] r) {
return arr(uint256(_a), _b, _c);
}
function arr(address _a, uint256 _b, uint256 _c, uint256 _d) internal pure returns (uint256[] r) {
return arr(uint256(_a), _b, _c, _d);
}
function arr(address _a, uint256 _b) internal pure returns (uint256[] r) {
return arr(uint256(_a), uint256(_b));
}
function arr(address _a, address _b, uint256 _c, uint256 _d, uint256 _e) internal pure returns (uint256[] r) {
return arr(uint256(_a), uint256(_b), _c, _d, _e);
}
function arr(address _a, address _b, address _c) internal pure returns (uint256[] r) {
return arr(uint256(_a), uint256(_b), uint256(_c));
}
function arr(address _a, address _b, uint256 _c) internal pure returns (uint256[] r) {
return arr(uint256(_a), uint256(_b), uint256(_c));
}
function arr(uint256 _a) internal pure returns (uint256[] r) {
r = new uint256[](1);
r[0] = _a;
}
function arr(uint256 _a, uint256 _b) internal pure returns (uint256[] r) {
r = new uint256[](2);
r[0] = _a;
r[1] = _b;
}
function arr(uint256 _a, uint256 _b, uint256 _c) internal pure returns (uint256[] r) {
r = new uint256[](3);
r[0] = _a;
r[1] = _b;
r[2] = _c;
}
function arr(uint256 _a, uint256 _b, uint256 _c, uint256 _d) internal pure returns (uint256[] r) {
r = new uint256[](4);
r[0] = _a;
r[1] = _b;
r[2] = _c;
r[3] = _d;
}
function arr(uint256 _a, uint256 _b, uint256 _c, uint256 _d, uint256 _e) internal pure returns (uint256[] r) {
r = new uint256[](5);
r[0] = _a;
r[1] = _b;
r[2] = _c;
r[3] = _d;
r[4] = _e;
}
}
contract ACLHelpers {
function decodeParamOp(uint256 _x) internal pure returns (uint8 b) {
return uint8(_x >> (8 * 30));
}
function decodeParamId(uint256 _x) internal pure returns (uint8 b) {
return uint8(_x >> (8 * 31));
}
function decodeParamsList(uint256 _x) internal pure returns (uint32 a, uint32 b, uint32 c) {
a = uint32(_x);
b = uint32(_x >> (8 * 4));
c = uint32(_x >> (8 * 8));
}
}/*
* SPDX-License-Identifier: MIT
*/
pragma solidity ^0.4.24;
interface IACL {
function initialize(address permissionsCreator) external;
// TODO: this should be external
// See https://github.com/ethereum/solidity/issues/4832
function hasPermission(address who, address where, bytes32 what, bytes how) public view returns (bool);
}/*
* SPDX-License-Identifier: MIT
*/
pragma solidity ^0.4.24;
interface IACLOracle {
function canPerform(address who, address where, bytes32 what, uint256[] how) external view returns (bool);
}/*
* SPDX-License-Identifier: MIT
*/
pragma solidity ^0.4.24;
import "../common/UnstructuredStorage.sol";
import "../kernel/IKernel.sol";
contract AppStorage {
using UnstructuredStorage for bytes32;
/* Hardcoded constants to save gas
bytes32 internal constant KERNEL_POSITION = keccak256("aragonOS.appStorage.kernel");
bytes32 internal constant APP_ID_POSITION = keccak256("aragonOS.appStorage.appId");
*/
bytes32 internal constant KERNEL_POSITION = 0x4172f0f7d2289153072b0a6ca36959e0cbe2efc3afe50fc81636caa96338137b;
bytes32 internal constant APP_ID_POSITION = 0xd625496217aa6a3453eecb9c3489dc5a53e6c67b444329ea2b2cbc9ff547639b;
function kernel() public view returns (IKernel) {
return IKernel(KERNEL_POSITION.getStorageAddress());
}
function appId() public view returns (bytes32) {
return APP_ID_POSITION.getStorageBytes32();
}
function setKernel(IKernel _kernel) internal {
KERNEL_POSITION.setStorageAddress(address(_kernel));
}
function setAppId(bytes32 _appId) internal {
APP_ID_POSITION.setStorageBytes32(_appId);
}
}/*
* SPDX-License-Identifier: MIT
*/
pragma solidity ^0.4.24;
import "./AppStorage.sol";
import "../acl/ACLSyntaxSugar.sol";
import "../common/Autopetrified.sol";
import "../common/ConversionHelpers.sol";
import "../common/ReentrancyGuard.sol";
import "../common/VaultRecoverable.sol";
import "../evmscript/EVMScriptRunner.sol";
// Contracts inheriting from AragonApp are, by default, immediately petrified upon deployment so
// that they can never be initialized.
// Unless overriden, this behaviour enforces those contracts to be usable only behind an AppProxy.
// ReentrancyGuard, EVMScriptRunner, and ACLSyntaxSugar are not directly used by this contract, but
// are included so that they are automatically usable by subclassing contracts
contract AragonApp is AppStorage, Autopetrified, VaultRecoverable, ReentrancyGuard, EVMScriptRunner, ACLSyntaxSugar {
string private constant ERROR_AUTH_FAILED = "APP_AUTH_FAILED";
modifier auth(bytes32 _role) {
require(canPerform(msg.sender, _role, new uint256[](0)), ERROR_AUTH_FAILED);
_;
}
modifier authP(bytes32 _role, uint256[] _params) {
require(canPerform(msg.sender, _role, _params), ERROR_AUTH_FAILED);
_;
}
/**
* @dev Check whether an action can be performed by a sender for a particular role on this app
* @param _sender Sender of the call
* @param _role Role on this app
* @param _params Permission params for the role
* @return Boolean indicating whether the sender has the permissions to perform the action.
* Always returns false if the app hasn't been initialized yet.
*/
function canPerform(address _sender, bytes32 _role, uint256[] _params) public view returns (bool) {
if (!hasInitialized()) {
return false;
}
IKernel linkedKernel = kernel();
if (address(linkedKernel) == address(0)) {
return false;
}
return linkedKernel.hasPermission(
_sender,
address(this),
_role,
ConversionHelpers.dangerouslyCastUintArrayToBytes(_params)
);
}
/**
* @dev Get the recovery vault for the app
* @return Recovery vault address for the app
*/
function getRecoveryVault() public view returns (address) {
// Funds recovery via a vault is only available when used with a kernel
return kernel().getRecoveryVault(); // if kernel is not set, it will revert
}
}/*
* SPDX-License-Identifier: MIT
*/
pragma solidity ^0.4.24;
import "./Petrifiable.sol";
contract Autopetrified is Petrifiable {
constructor() public {
// Immediately petrify base (non-proxy) instances of inherited contracts on deploy.
// This renders them uninitializable (and unusable without a proxy).
petrify();
}
}pragma solidity ^0.4.24;
library ConversionHelpers {
string private constant ERROR_IMPROPER_LENGTH = "CONVERSION_IMPROPER_LENGTH";
function dangerouslyCastUintArrayToBytes(uint256[] memory _input) internal pure returns (bytes memory output) {
// Force cast the uint256[] into a bytes array, by overwriting its length
// Note that the bytes array doesn't need to be initialized as we immediately overwrite it
// with the input and a new length. The input becomes invalid from this point forward.
uint256 byteLength = _input.length * 32;
assembly {
output := _input
mstore(output, byteLength)
}
}
function dangerouslyCastBytesToUintArray(bytes memory _input) internal pure returns (uint256[] memory output) {
// Force cast the bytes array into a uint256[], by overwriting its length
// Note that the uint256[] doesn't need to be initialized as we immediately overwrite it
// with the input and a new length. The input becomes invalid from this point forward.
uint256 intsLength = _input.length / 32;
require(_input.length == intsLength * 32, ERROR_IMPROPER_LENGTH);
assembly {
output := _input
mstore(output, intsLength)
}
}
}/*
* SPDX-License-Identifier: MIT
*/
pragma solidity ^0.4.24;
// aragonOS and aragon-apps rely on address(0) to denote native ETH, in
// contracts where both tokens and ETH are accepted
contract EtherTokenConstant {
address internal constant ETH = address(0);
}/*
* SPDX-License-Identifier: MIT
*/
pragma solidity ^0.4.24;
import "./TimeHelpers.sol";
import "./UnstructuredStorage.sol";
contract Initializable is TimeHelpers {
using UnstructuredStorage for bytes32;
// keccak256("aragonOS.initializable.initializationBlock")
bytes32 internal constant INITIALIZATION_BLOCK_POSITION = 0xebb05b386a8d34882b8711d156f463690983dc47815980fb82aeeff1aa43579e;
string private constant ERROR_ALREADY_INITIALIZED = "INIT_ALREADY_INITIALIZED";
string private constant ERROR_NOT_INITIALIZED = "INIT_NOT_INITIALIZED";
modifier onlyInit {
require(getInitializationBlock() == 0, ERROR_ALREADY_INITIALIZED);
_;
}
modifier isInitialized {
require(hasInitialized(), ERROR_NOT_INITIALIZED);
_;
}
/**
* @return Block number in which the contract was initialized
*/
function getInitializationBlock() public view returns (uint256) {
return INITIALIZATION_BLOCK_POSITION.getStorageUint256();
}
/**
* @return Whether the contract has been initialized by the time of the current block
*/
function hasInitialized() public view returns (bool) {
uint256 initializationBlock = getInitializationBlock();
return initializationBlock != 0 && getBlockNumber() >= initializationBlock;
}
/**
* @dev Function to be called by top level contract after initialization has finished.
*/
function initialized() internal onlyInit {
INITIALIZATION_BLOCK_POSITION.setStorageUint256(getBlockNumber());
}
/**
* @dev Function to be called by top level contract after initialization to enable the contract
* at a future block number rather than immediately.
*/
function initializedAt(uint256 _blockNumber) internal onlyInit {
INITIALIZATION_BLOCK_POSITION.setStorageUint256(_blockNumber);
}
}/*
* SPDX-License-Identifier: MIT
*/
pragma solidity ^0.4.24;
contract IsContract {
/*
* NOTE: this should NEVER be used for authentication
* (see pitfalls: https://github.com/fergarrui/ethereum-security/tree/master/contracts/extcodesize).
*
* This is only intended to be used as a sanity check that an address is actually a contract,
* RATHER THAN an address not being a contract.
*/
function isContract(address _target) internal view returns (bool) {
if (_target == address(0)) {
return false;
}
uint256 size;
assembly { size := extcodesize(_target) }
return size > 0;
}
}/*
* SPDX-License-Identifier: MIT
*/
pragma solidity ^0.4.24;
interface IVaultRecoverable {
event RecoverToVault(address indexed vault, address indexed token, uint256 amount);
function transferToVault(address token) external;
function allowRecoverability(address token) external view returns (bool);
function getRecoveryVault() external view returns (address);
}/*
* SPDX-License-Identifier: MIT
*/
pragma solidity ^0.4.24;
import "./Initializable.sol";
contract Petrifiable is Initializable {
// Use block UINT256_MAX (which should be never) as the initializable date
uint256 internal constant PETRIFIED_BLOCK = uint256(-1);
function isPetrified() public view returns (bool) {
return getInitializationBlock() == PETRIFIED_BLOCK;
}
/**
* @dev Function to be called by top level contract to prevent being initialized.
* Useful for freezing base contracts when they're used behind proxies.
*/
function petrify() internal onlyInit {
initializedAt(PETRIFIED_BLOCK);
}
}/*
* SPDX-License-Identifier: MIT
*/
pragma solidity ^0.4.24;
import "../common/UnstructuredStorage.sol";
contract ReentrancyGuard {
using UnstructuredStorage for bytes32;
/* Hardcoded constants to save gas
bytes32 internal constant REENTRANCY_MUTEX_POSITION = keccak256("aragonOS.reentrancyGuard.mutex");
*/
bytes32 private constant REENTRANCY_MUTEX_POSITION = 0xe855346402235fdd185c890e68d2c4ecad599b88587635ee285bce2fda58dacb;
string private constant ERROR_REENTRANT = "REENTRANCY_REENTRANT_CALL";
modifier nonReentrant() {
// Ensure mutex is unlocked
require(!REENTRANCY_MUTEX_POSITION.getStorageBool(), ERROR_REENTRANT);
// Lock mutex before function call
REENTRANCY_MUTEX_POSITION.setStorageBool(true);
// Perform function call
_;
// Unlock mutex after function call
REENTRANCY_MUTEX_POSITION.setStorageBool(false);
}
}// Inspired by AdEx (https://github.com/AdExNetwork/adex-protocol-eth/blob/b9df617829661a7518ee10f4cb6c4108659dd6d5/contracts/libs/SafeERC20.sol)
// and 0x (https://github.com/0xProject/0x-monorepo/blob/737d1dc54d72872e24abce5a1dbe1b66d35fa21a/contracts/protocol/contracts/protocol/AssetProxy/ERC20Proxy.sol#L143)
pragma solidity ^0.4.24;
import "../lib/token/ERC20.sol";
library SafeERC20 {
// Before 0.5, solidity has a mismatch between `address.transfer()` and `token.transfer()`:
// https://github.com/ethereum/solidity/issues/3544
bytes4 private constant TRANSFER_SELECTOR = 0xa9059cbb;
string private constant ERROR_TOKEN_BALANCE_REVERTED = "SAFE_ERC_20_BALANCE_REVERTED";
string private constant ERROR_TOKEN_ALLOWANCE_REVERTED = "SAFE_ERC_20_ALLOWANCE_REVERTED";
function invokeAndCheckSuccess(address _addr, bytes memory _calldata)
private
returns (bool)
{
bool ret;
assembly {
let ptr := mload(0x40) // free memory pointer
let success := call(
gas, // forward all gas
_addr, // address
0, // no value
add(_calldata, 0x20), // calldata start
mload(_calldata), // calldata length
ptr, // write output over free memory
0x20 // uint256 return
)
if gt(success, 0) {
// Check number of bytes returned from last function call
switch returndatasize
// No bytes returned: assume success
case 0 {
ret := 1
}
// 32 bytes returned: check if non-zero
case 0x20 {
// Only return success if returned data was true
// Already have output in ptr
ret := eq(mload(ptr), 1)
}
// Not sure what was returned: don't mark as success
default { }
}
}
return ret;
}
function staticInvoke(address _addr, bytes memory _calldata)
private
view
returns (bool, uint256)
{
bool success;
uint256 ret;
assembly {
let ptr := mload(0x40) // free memory pointer
success := staticcall(
gas, // forward all gas
_addr, // address
add(_calldata, 0x20), // calldata start
mload(_calldata), // calldata length
ptr, // write output over free memory
0x20 // uint256 return
)
if gt(success, 0) {
ret := mload(ptr)
}
}
return (success, ret);
}
/**
* @dev Same as a standards-compliant ERC20.transfer() that never reverts (returns false).
* Note that this makes an external call to the token.
*/
function safeTransfer(ERC20 _token, address _to, uint256 _amount) internal returns (bool) {
bytes memory transferCallData = abi.encodeWithSelector(
TRANSFER_SELECTOR,
_to,
_amount
);
return invokeAndCheckSuccess(_token, transferCallData);
}
/**
* @dev Same as a standards-compliant ERC20.transferFrom() that never reverts (returns false).
* Note that this makes an external call to the token.
*/
function safeTransferFrom(ERC20 _token, address _from, address _to, uint256 _amount) internal returns (bool) {
bytes memory transferFromCallData = abi.encodeWithSelector(
_token.transferFrom.selector,
_from,
_to,
_amount
);
return invokeAndCheckSuccess(_token, transferFromCallData);
}
/**
* @dev Same as a standards-compliant ERC20.approve() that never reverts (returns false).
* Note that this makes an external call to the token.
*/
function safeApprove(ERC20 _token, address _spender, uint256 _amount) internal returns (bool) {
bytes memory approveCallData = abi.encodeWithSelector(
_token.approve.selector,
_spender,
_amount
);
return invokeAndCheckSuccess(_token, approveCallData);
}
/**
* @dev Static call into ERC20.balanceOf().
* Reverts if the call fails for some reason (should never fail).
*/
function staticBalanceOf(ERC20 _token, address _owner) internal view returns (uint256) {
bytes memory balanceOfCallData = abi.encodeWithSelector(
_token.balanceOf.selector,
_owner
);
(bool success, uint256 tokenBalance) = staticInvoke(_token, balanceOfCallData);
require(success, ERROR_TOKEN_BALANCE_REVERTED);
return tokenBalance;
}
/**
* @dev Static call into ERC20.allowance().
* Reverts if the call fails for some reason (should never fail).
*/
function staticAllowance(ERC20 _token, address _owner, address _spender) internal view returns (uint256) {
bytes memory allowanceCallData = abi.encodeWithSelector(
_token.allowance.selector,
_owner,
_spender
);
(bool success, uint256 allowance) = staticInvoke(_token, allowanceCallData);
require(success, ERROR_TOKEN_ALLOWANCE_REVERTED);
return allowance;
}
/**
* @dev Static call into ERC20.totalSupply().
* Reverts if the call fails for some reason (should never fail).
*/
function staticTotalSupply(ERC20 _token) internal view returns (uint256) {
bytes memory totalSupplyCallData = abi.encodeWithSelector(_token.totalSupply.selector);
(bool success, uint256 totalSupply) = staticInvoke(_token, totalSupplyCallData);
require(success, ERROR_TOKEN_ALLOWANCE_REVERTED);
return totalSupply;
}
}/*
* SPDX-License-Identifier: MIT
*/
pragma solidity ^0.4.24;
import "./Uint256Helpers.sol";
contract TimeHelpers {
using Uint256Helpers for uint256;
/**
* @dev Returns the current block number.
* Using a function rather than `block.number` allows us to easily mock the block number in
* tests.
*/
function getBlockNumber() internal view returns (uint256) {
return block.number;
}
/**
* @dev Returns the current block number, converted to uint64.
* Using a function rather than `block.number` allows us to easily mock the block number in
* tests.
*/
function getBlockNumber64() internal view returns (uint64) {
return getBlockNumber().toUint64();
}
/**
* @dev Returns the current timestamp.
* Using a function rather than `block.timestamp` allows us to easily mock it in
* tests.
*/
function getTimestamp() internal view returns (uint256) {
return block.timestamp; // solium-disable-line security/no-block-members
}
/**
* @dev Returns the current timestamp, converted to uint64.
* Using a function rather than `block.timestamp` allows us to easily mock it in
* tests.
*/
function getTimestamp64() internal view returns (uint64) {
return getTimestamp().toUint64();
}
}pragma solidity ^0.4.24;
library Uint256Helpers {
uint256 private constant MAX_UINT64 = uint64(-1);
string private constant ERROR_NUMBER_TOO_BIG = "UINT64_NUMBER_TOO_BIG";
function toUint64(uint256 a) internal pure returns (uint64) {
require(a <= MAX_UINT64, ERROR_NUMBER_TOO_BIG);
return uint64(a);
}
}/*
* SPDX-License-Identifier: MIT
*/
pragma solidity ^0.4.24;
library UnstructuredStorage {
function getStorageBool(bytes32 position) internal view returns (bool data) {
assembly { data := sload(position) }
}
function getStorageAddress(bytes32 position) internal view returns (address data) {
assembly { data := sload(position) }
}
function getStorageBytes32(bytes32 position) internal view returns (bytes32 data) {
assembly { data := sload(position) }
}
function getStorageUint256(bytes32 position) internal view returns (uint256 data) {
assembly { data := sload(position) }
}
function setStorageBool(bytes32 position, bool data) internal {
assembly { sstore(position, data) }
}
function setStorageAddress(bytes32 position, address data) internal {
assembly { sstore(position, data) }
}
function setStorageBytes32(bytes32 position, bytes32 data) internal {
assembly { sstore(position, data) }
}
function setStorageUint256(bytes32 position, uint256 data) internal {
assembly { sstore(position, data) }
}
}/*
* SPDX-License-Identifier: MIT
*/
pragma solidity ^0.4.24;
import "../lib/token/ERC20.sol";
import "./EtherTokenConstant.sol";
import "./IsContract.sol";
import "./IVaultRecoverable.sol";
import "./SafeERC20.sol";
contract VaultRecoverable is IVaultRecoverable, EtherTokenConstant, IsContract {
using SafeERC20 for ERC20;
string private constant ERROR_DISALLOWED = "RECOVER_DISALLOWED";
string private constant ERROR_VAULT_NOT_CONTRACT = "RECOVER_VAULT_NOT_CONTRACT";
string private constant ERROR_TOKEN_TRANSFER_FAILED = "RECOVER_TOKEN_TRANSFER_FAILED";
/**
* @notice Send funds to recovery Vault. This contract should never receive funds,
* but in case it does, this function allows one to recover them.
* @param _token Token balance to be sent to recovery vault.
*/
function transferToVault(address _token) external {
require(allowRecoverability(_token), ERROR_DISALLOWED);
address vault = getRecoveryVault();
require(isContract(vault), ERROR_VAULT_NOT_CONTRACT);
uint256 balance;
if (_token == ETH) {
balance = address(this).balance;
vault.transfer(balance);
} else {
ERC20 token = ERC20(_token);
balance = token.staticBalanceOf(this);
require(token.safeTransfer(vault, balance), ERROR_TOKEN_TRANSFER_FAILED);
}
emit RecoverToVault(vault, _token, balance);
}
/**
* @dev By default deriving from AragonApp makes it recoverable
* @param token Token address that would be recovered
* @return bool whether the app allows the recovery
*/
function allowRecoverability(address token) public view returns (bool) {
return true;
}
// Cast non-implemented interface to be public so we can use it internally
function getRecoveryVault() public view returns (address);
}/*
* SPDX-License-Identifier: MIT
*/
pragma solidity ^0.4.24;
import "./IEVMScriptExecutor.sol";
import "./IEVMScriptRegistry.sol";
import "../apps/AppStorage.sol";
import "../kernel/KernelConstants.sol";
import "../common/Initializable.sol";
contract EVMScriptRunner is AppStorage, Initializable, EVMScriptRegistryConstants, KernelNamespaceConstants {
string private constant ERROR_EXECUTOR_UNAVAILABLE = "EVMRUN_EXECUTOR_UNAVAILABLE";
string private constant ERROR_PROTECTED_STATE_MODIFIED = "EVMRUN_PROTECTED_STATE_MODIFIED";
/* This is manually crafted in assembly
string private constant ERROR_EXECUTOR_INVALID_RETURN = "EVMRUN_EXECUTOR_INVALID_RETURN";
*/
event ScriptResult(address indexed executor, bytes script, bytes input, bytes returnData);
function getEVMScriptExecutor(bytes _script) public view returns (IEVMScriptExecutor) {
return IEVMScriptExecutor(getEVMScriptRegistry().getScriptExecutor(_script));
}
function getEVMScriptRegistry() public view returns (IEVMScriptRegistry) {
address registryAddr = kernel().getApp(KERNEL_APP_ADDR_NAMESPACE, EVMSCRIPT_REGISTRY_APP_ID);
return IEVMScriptRegistry(registryAddr);
}
function runScript(bytes _script, bytes _input, address[] _blacklist)
internal
isInitialized
protectState
returns (bytes)
{
IEVMScriptExecutor executor = getEVMScriptExecutor(_script);
require(address(executor) != address(0), ERROR_EXECUTOR_UNAVAILABLE);
bytes4 sig = executor.execScript.selector;
bytes memory data = abi.encodeWithSelector(sig, _script, _input, _blacklist);
bytes memory output;
assembly {
let success := delegatecall(
gas, // forward all gas
executor, // address
add(data, 0x20), // calldata start
mload(data), // calldata length
0, // don't write output (we'll handle this ourselves)
0 // don't write output
)
output := mload(0x40) // free mem ptr get
switch success
case 0 {
// If the call errored, forward its full error data
returndatacopy(output, 0, returndatasize)
revert(output, returndatasize)
}
default {
switch gt(returndatasize, 0x3f)
case 0 {
// Need at least 0x40 bytes returned for properly ABI-encoded bytes values,
// revert with "EVMRUN_EXECUTOR_INVALID_RETURN"
// See remix: doing a `revert("EVMRUN_EXECUTOR_INVALID_RETURN")` always results in
// this memory layout
mstore(output, 0x08c379a000000000000000000000000000000000000000000000000000000000) // error identifier
mstore(add(output, 0x04), 0x0000000000000000000000000000000000000000000000000000000000000020) // starting offset
mstore(add(output, 0x24), 0x000000000000000000000000000000000000000000000000000000000000001e) // reason length
mstore(add(output, 0x44), 0x45564d52554e5f4558454355544f525f494e56414c49445f52455455524e0000) // reason
revert(output, 100) // 100 = 4 + 3 * 32 (error identifier + 3 words for the ABI encoded error)
}
default {
// Copy result
//
// Needs to perform an ABI decode for the expected `bytes` return type of
// `executor.execScript()` as solidity will automatically ABI encode the returned bytes as:
// [ position of the first dynamic length return value = 0x20 (32 bytes) ]
// [ output length (32 bytes) ]
// [ output content (N bytes) ]
//
// Perform the ABI decode by ignoring the first 32 bytes of the return data
let copysize := sub(returndatasize, 0x20)
returndatacopy(output, 0x20, copysize)
mstore(0x40, add(output, copysize)) // free mem ptr set
}
}
}
emit ScriptResult(address(executor), _script, _input, output);
return output;
}
modifier protectState {
address preKernel = address(kernel());
bytes32 preAppId = appId();
_; // exec
require(address(kernel()) == preKernel, ERROR_PROTECTED_STATE_MODIFIED);
require(appId() == preAppId, ERROR_PROTECTED_STATE_MODIFIED);
}
}/*
* SPDX-License-Identifier: MIT
*/
pragma solidity ^0.4.24;
interface IEVMScriptExecutor {
function execScript(bytes script, bytes input, address[] blacklist) external returns (bytes);
function executorType() external pure returns (bytes32);
}/*
* SPDX-License-Identifier: MIT
*/
pragma solidity ^0.4.24;
import "./IEVMScriptExecutor.sol";
contract EVMScriptRegistryConstants {
/* Hardcoded constants to save gas
bytes32 internal constant EVMSCRIPT_REGISTRY_APP_ID = apmNamehash("evmreg");
*/
bytes32 internal constant EVMSCRIPT_REGISTRY_APP_ID = 0xddbcfd564f642ab5627cf68b9b7d374fb4f8a36e941a75d89c87998cef03bd61;
}
interface IEVMScriptRegistry {
function addScriptExecutor(IEVMScriptExecutor executor) external returns (uint id);
function disableScriptExecutor(uint256 executorId) external;
// TODO: this should be external
// See https://github.com/ethereum/solidity/issues/4832
function getScriptExecutor(bytes script) public view returns (IEVMScriptExecutor);
}/*
* SPDX-License-Identifier: MIT
*/
pragma solidity ^0.4.24;
import "../acl/IACL.sol";
import "../common/IVaultRecoverable.sol";
interface IKernelEvents {
event SetApp(bytes32 indexed namespace, bytes32 indexed appId, address app);
}
// This should be an interface, but interfaces can't inherit yet :(
contract IKernel is IKernelEvents, IVaultRecoverable {
function acl() public view returns (IACL);
function hasPermission(address who, address where, bytes32 what, bytes how) public view returns (bool);
function setApp(bytes32 namespace, bytes32 appId, address app) public;
function getApp(bytes32 namespace, bytes32 appId) public view returns (address);
}/*
* SPDX-License-Identifier: MIT
*/
pragma solidity ^0.4.24;
contract KernelAppIds {
/* Hardcoded constants to save gas
bytes32 internal constant KERNEL_CORE_APP_ID = apmNamehash("kernel");
bytes32 internal constant KERNEL_DEFAULT_ACL_APP_ID = apmNamehash("acl");
bytes32 internal constant KERNEL_DEFAULT_VAULT_APP_ID = apmNamehash("vault");
*/
bytes32 internal constant KERNEL_CORE_APP_ID = 0x3b4bf6bf3ad5000ecf0f989d5befde585c6860fea3e574a4fab4c49d1c177d9c;
bytes32 internal constant KERNEL_DEFAULT_ACL_APP_ID = 0xe3262375f45a6e2026b7e7b18c2b807434f2508fe1a2a3dfb493c7df8f4aad6a;
bytes32 internal constant KERNEL_DEFAULT_VAULT_APP_ID = 0x7e852e0fcfce6551c13800f1e7476f982525c2b5277ba14b24339c68416336d1;
}
contract KernelNamespaceConstants {
/* Hardcoded constants to save gas
bytes32 internal constant KERNEL_CORE_NAMESPACE = keccak256("core");
bytes32 internal constant KERNEL_APP_BASES_NAMESPACE = keccak256("base");
bytes32 internal constant KERNEL_APP_ADDR_NAMESPACE = keccak256("app");
*/
bytes32 internal constant KERNEL_CORE_NAMESPACE = 0xc681a85306374a5ab27f0bbc385296a54bcd314a1948b6cf61c4ea1bc44bb9f8;
bytes32 internal constant KERNEL_APP_BASES_NAMESPACE = 0xf1f3eb40f5bc1ad1344716ced8b8a0431d840b5783aea1fd01786bc26f35ac0f;
bytes32 internal constant KERNEL_APP_ADDR_NAMESPACE = 0xd6f028ca0e8edb4a8c9757ca4fdccab25fa1e0317da1188108f7d2dee14902fb;
}// See https://github.com/OpenZeppelin/openzeppelin-solidity/blob/a9f910d34f0ab33a1ae5e714f69f9596a02b4d91/contracts/token/ERC20/ERC20.sol
pragma solidity ^0.4.24;
/**
* @title ERC20 interface
* @dev see https://github.com/ethereum/EIPs/issues/20
*/
contract ERC20 {
function totalSupply() public view returns (uint256);
function balanceOf(address _who) public view returns (uint256);
function allowance(address _owner, address _spender)
public view returns (uint256);
function transfer(address _to, uint256 _value) public returns (bool);
function approve(address _spender, uint256 _value)
public returns (bool);
function transferFrom(address _from, address _to, uint256 _value)
public returns (bool);
event Transfer(
address indexed from,
address indexed to,
uint256 value
);
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
}{
"optimizer": {
"enabled": true,
"runs": 200
},
"evmVersion": "constantinople",
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"libraries": {}
}Contract ABI
API[{"constant":true,"inputs":[],"name":"hasInitialized","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_app","type":"address"},{"name":"_role","type":"bytes32"}],"name":"createBurnedPermission","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_app","type":"address"},{"name":"_role","type":"bytes32"}],"name":"burnPermissionManager","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_entity","type":"address"},{"name":"_app","type":"address"},{"name":"_role","type":"bytes32"}],"name":"grantPermission","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_entity","type":"address"},{"name":"_app","type":"address"},{"name":"_role","type":"bytes32"}],"name":"getPermissionParamsLength","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_paramsHash","type":"bytes32"},{"name":"_who","type":"address"},{"name":"_where","type":"address"},{"name":"_what","type":"bytes32"},{"name":"_how","type":"uint256[]"}],"name":"evalParams","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"NO_PERMISSION","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_script","type":"bytes"}],"name":"getEVMScriptExecutor","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getRecoveryVault","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"CREATE_PERMISSIONS_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_entity","type":"address"},{"name":"_app","type":"address"},{"name":"_role","type":"bytes32"},{"name":"_params","type":"uint256[]"}],"name":"grantPermissionP","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_who","type":"address"},{"name":"_where","type":"address"},{"name":"_what","type":"bytes32"}],"name":"hasPermission","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"token","type":"address"}],"name":"allowRecoverability","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"appId","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getInitializationBlock","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_entity","type":"address"},{"name":"_app","type":"address"},{"name":"_role","type":"bytes32"}],"name":"revokePermission","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_token","type":"address"}],"name":"transferToVault","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_entity","type":"address"},{"name":"_app","type":"address"},{"name":"_role","type":"bytes32"},{"name":"_index","type":"uint256"}],"name":"getPermissionParam","outputs":[{"name":"","type":"uint8"},{"name":"","type":"uint8"},{"name":"","type":"uint240"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_sender","type":"address"},{"name":"_role","type":"bytes32"},{"name":"_params","type":"uint256[]"}],"name":"canPerform","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getEVMScriptRegistry","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ANY_ENTITY","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_app","type":"address"},{"name":"_role","type":"bytes32"}],"name":"removePermissionManager","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_newManager","type":"address"},{"name":"_app","type":"address"},{"name":"_role","type":"bytes32"}],"name":"setPermissionManager","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_app","type":"address"},{"name":"_role","type":"bytes32"}],"name":"getPermissionManager","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_entity","type":"address"},{"name":"_app","type":"address"},{"name":"_role","type":"bytes32"},{"name":"_manager","type":"address"}],"name":"createPermission","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_permissionsCreator","type":"address"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"EMPTY_PARAM_HASH","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"kernel","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isPetrified","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"BURN_ENTITY","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_who","type":"address"},{"name":"_where","type":"address"},{"name":"_what","type":"bytes32"},{"name":"_how","type":"uint256[]"}],"name":"hasPermission","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_who","type":"address"},{"name":"_where","type":"address"},{"name":"_what","type":"bytes32"},{"name":"_how","type":"bytes"}],"name":"hasPermission","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"entity","type":"address"},{"indexed":true,"name":"app","type":"address"},{"indexed":true,"name":"role","type":"bytes32"},{"indexed":false,"name":"allowed","type":"bool"}],"name":"SetPermission","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"entity","type":"address"},{"indexed":true,"name":"app","type":"address"},{"indexed":true,"name":"role","type":"bytes32"},{"indexed":false,"name":"paramsHash","type":"bytes32"}],"name":"SetPermissionParams","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"app","type":"address"},{"indexed":true,"name":"role","type":"bytes32"},{"indexed":true,"name":"manager","type":"address"}],"name":"ChangePermissionManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"executor","type":"address"},{"indexed":false,"name":"script","type":"bytes"},{"indexed":false,"name":"input","type":"bytes"},{"indexed":false,"name":"returnData","type":"bytes"}],"name":"ScriptResult","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"vault","type":"address"},{"indexed":true,"name":"token","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"RecoverToVault","type":"event"}]Contract Creation Code
6080604052620000146200001a60201b60201c565b62000231565b6200002a6200011c60201b60201c565b60408051808201909152601881527f494e49545f414c52454144595f494e495449414c495a454400000000000000006020820152901562000106576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015620000ca578181015183820152602001620000b0565b50505050905090810190601f168015620000f85780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506200011a6000196200014f60201b60201c565b565b60006200014a6000805160206200292383398151915260001b600019166200022960201b62001e001760201c565b905090565b6200015f6200011c60201b60201c565b60408051808201909152601881527f494e49545f414c52454144595f494e495449414c495a4544000000000000000060208201529015620001fe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252838181518152602001915080519060200190808383600083811015620000ca578181015183820152602001620000b0565b506200022660008051602062002923833981519152826200022d602090811b6200262317901c565b50565b5490565b9055565b6126e280620002416000396000f3006080604052600436106101795760003560e01c63ffffffff1680630803fac01461017e5780630808343e146101a757806309699ff5146101cd5780630a8ed3db146101f157806315949ed71461021b5780631b5e75be146102575780631d63ff2b146102cc5780632914b9bd146102e157806332f0a3b5146103565780633d6ab68f1461036b5780636815c992146103805780636d6712d8146103f45780637e7db6e11461041e57806380afdea81461043f5780638b3dd749146104545780639d0effdb146104695780639d4941d814610493578063a03c5832146104b4578063a1658fad1461050e578063a479e50814610575578063a5ed8bf81461058a578063a885508a1461059f578063afd925df146105c3578063b1905727146105ed578063be03847814610611578063c4d66de814610642578063c513f66e14610663578063d4aae0c414610678578063de4796ed1461068d578063f516bc0e146106a2578063f520b58d146106b7578063fdef91061461072b575b600080fd5b34801561018a57600080fd5b5061019361079a565b604080519115158252519081900360200190f35b3480156101b357600080fd5b506101cb600160a060020a03600435166024356107c3565b005b3480156101d957600080fd5b506101cb600160a060020a036004351660243561096a565b3480156101fd57600080fd5b506101cb600160a060020a0360043581169060243516604435610a06565b34801561022757600080fd5b50610245600160a060020a0360043581169060243516604435610a42565b60408051918252519081900360200190f35b34801561026357600080fd5b5060408051602060046084358181013583810280860185019096528085526101939583359560248035600160a060020a039081169760443590911696606435963696919560a495949091019282919085019084908082843750949750610a849650505050505050565b3480156102d857600080fd5b50610245610abf565b3480156102ed57600080fd5b506040805160206004803580820135601f810184900484028501840190955284845261033a943694929360249392840191908190840183828082843750949750610ac49650505050505050565b60408051600160a060020a039092168252519081900360200190f35b34801561036257600080fd5b5061033a610ba7565b34801561037757600080fd5b50610245610c1c565b34801561038c57600080fd5b5060408051606435600481810135602081810285810182019096528185526101cb95600160a060020a0384358116966024803590921696604435963696909560849593949290920192909182919085019084908082843750949750610c2e9650505050505050565b34801561040057600080fd5b50610193600160a060020a0360043581169060243516604435610cf7565b34801561042a57600080fd5b50610193600160a060020a0360043516610d1e565b34801561044b57600080fd5b50610245610d24565b34801561046057600080fd5b50610245610d54565b34801561047557600080fd5b506101cb600160a060020a0360043581169060243516604435610d7f565b34801561049f57600080fd5b506101cb600160a060020a0360043516610e16565b3480156104c057600080fd5b506104e1600160a060020a03600435811690602435166044356064356110a5565b6040805160ff9485168152929093166020830152600160f060020a03168183015290519081900360600190f35b34801561051a57600080fd5b506040805160206004604435818101358381028086018501909652808552610193958335600160a060020a03169560248035963696956064959394920192918291850190849080828437509497506111239650505050505050565b34801561058157600080fd5b5061033a61126e565b34801561059657600080fd5b5061033a611323565b3480156105ab57600080fd5b506101cb600160a060020a0360043516602435611329565b3480156105cf57600080fd5b506101cb600160a060020a03600435811690602435166044356113bf565b3480156105f957600080fd5b5061033a600160a060020a0360043516602435611454565b34801561061d57600080fd5b506101cb600160a060020a036004358116906024358116906044359060643516611485565b34801561064e57600080fd5b506101cb600160a060020a03600435166115e7565b34801561066f57600080fd5b50610245611732565b34801561068457600080fd5b5061033a611744565b34801561069957600080fd5b5061019361176f565b3480156106ae57600080fd5b5061033a611782565b3480156106c357600080fd5b50604080516064356004818101356020818102858101820190965281855261019395600160a060020a03843581169660248035909216966044359636969095608495939492909201929091829190850190849080828437509497506117879650505050505050565b34801561073757600080fd5b50604080516020601f60643560048181013592830184900484028501840190955281845261019394600160a060020a03813581169560248035909216956044359536956084940191819084018382808284375094975061182b9650505050505050565b6000806107a5610d54565b905080158015906107bd5750806107ba611841565b10155b91505090565b60408051600080825260208201909252600080516020612677833981519152916107f39133918491905b50611123565b60408051808201909152600f81527f4150505f415554485f4641494c4544000000000000000000000000000000000060208201529015156108b55760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561087a578181015183820152602001610862565b50505050905090810190601f1680156108a75780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50828260006108c48383611454565b600160a060020a0316146040805190810160405280601481526020017f41434c5f4558495354454e545f4d414e414745520000000000000000000000008152509015156109565760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561087a578181015183820152602001610862565b5061096360018686611845565b5050505050565b81816109768282611454565b6040805180820190915260138152600080516020612697833981519152602082015290600160a060020a031633146109f35760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561087a578181015183820152602001610862565b50610a0060018585611845565b50505050565b610a3d8383836000604051908082528060200260200182016040528015610a37578160200160208202803883390190505b50610c2e565b505050565b600060016000806000610a568888886118c4565b81526020808201929092526040908101600090812054845291830193909352910190205490505b9392505050565b6000600080516020612657833981519152861415610aa457506001610ab6565b610ab38660008787878761198f565b90505b95945050505050565b600081565b6000610ace61126e565b600160a060020a03166304bf2a7f836040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610b29578181015183820152602001610b11565b50505050905090810190601f168015610b565780820380516001836020036101000a031916815260200191505b5092505050602060405180830381600087803b158015610b7557600080fd5b505af1158015610b89573d6000803e3d6000fd5b505050506040513d6020811015610b9f57600080fd5b505192915050565b6000610bb1611744565b600160a060020a03166332f0a3b56040518163ffffffff1660e01b8152600401602060405180830381600087803b158015610beb57600080fd5b505af1158015610bff573d6000803e3d6000fd5b505050506040513d6020811015610c1557600080fd5b5051905090565b60008051602061267783398151915281565b60008383610c3c8282611454565b6040805180820190915260138152600080516020612697833981519152602082015290600160a060020a03163314610cb95760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561087a578181015183820152602001610862565b506000845111610cd757600080516020612657833981519152610ce0565b610ce084611b7c565b9250610cee87878786611d1e565b50505050505050565b60408051600080825260208201909252610d1385858584611787565b91505b509392505050565b50600190565b6000610d4f7fd625496217aa6a3453eecb9c3489dc5a53e6c67b444329ea2b2cbc9ff547639b611e00565b905090565b6000610d4f7febb05b386a8d34882b8711d156f463690983dc47815980fb82aeeff1aa43579e611e00565b8181610d8b8282611454565b6040805180820190915260138152600080516020612697833981519152602082015290600160a060020a03163314610e085760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561087a578181015183820152602001610862565b506109638585856000611d1e565b6000806000610e2484610d1e565b60408051808201909152601281527f5245434f5645525f444953414c4c4f57454400000000000000000000000000006020820152901515610eaa5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561087a578181015183820152602001610862565b50610eb3610ba7565b9250610ebe83611e08565b60408051808201909152601a81527f5245434f5645525f5641554c545f4e4f545f434f4e54524143540000000000006020820152901515610f445760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561087a578181015183820152602001610862565b50600160a060020a0384161515610f955760405130319250600160a060020a0384169083156108fc029084906000818181858888f19350505050158015610f8f573d6000803e3d6000fd5b50611054565b5082610fb0600160a060020a0382163063ffffffff611e3516565b9150610fcc600160a060020a038216848463ffffffff611f3516565b60408051808201909152601d81527f5245434f5645525f544f4b454e5f5452414e534645525f4641494c454400000060208201529015156110525760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561087a578181015183820152602001610862565b505b83600160a060020a031683600160a060020a03167f596caf56044b55fb8c4ca640089bbc2b63cae3e978b851f5745cbb7c5b288e02846040518082815260200191505060405180910390a350505050565b600080600080600160008060006110bd8c8c8c6118c4565b81526020808201929092526040908101600090812054845291830193909352910190208054869081106110ec57fe5b60009182526020909120015460ff8082169a6101008304909116995062010000909104600160f060020a0316975095505050505050565b60008061112e61079a565b151561113d5760009150610d16565b611145611744565b9050600160a060020a03811615156111605760009150610d16565b80600160a060020a031663fdef910686308761117b88611fa2565b60405163ffffffff861660e01b8152600160a060020a03808616600483019081529085166024830152604482018490526080606483019081528351608484015283519192909160a490910190602085019080838360005b838110156111ea5781810151838201526020016111d2565b50505050905090810190601f1680156112175780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b15801561123957600080fd5b505af115801561124d573d6000803e3d6000fd5b505050506040513d602081101561126357600080fd5b505195945050505050565b600080611279611744565b604080517fbe00bbd80000000000000000000000000000000000000000000000000000000081527fd6f028ca0e8edb4a8c9757ca4fdccab25fa1e0317da1188108f7d2dee14902fb60048201527fddbcfd564f642ab5627cf68b9b7d374fb4f8a36e941a75d89c87998cef03bd6160248201529051600160a060020a03929092169163be00bbd8916044808201926020929091908290030181600087803b158015610b7557600080fd5b60001981565b81816113358282611454565b6040805180820190915260138152600080516020612697833981519152602082015290600160a060020a031633146113b25760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561087a578181015183820152602001610862565b50610a0060008585611845565b81816113cb8282611454565b6040805180820190915260138152600080516020612697833981519152602082015290600160a060020a031633146114485760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561087a578181015183820152602001610862565b50610963858585611845565b6000600260006114648585611fac565b8152602081019190915260400160002054600160a060020a03169392505050565b60408051600080825260208201909252600080516020612677833981519152916114b39133918491906107ed565b60408051808201909152600f81527f4150505f415554485f4641494c4544000000000000000000000000000000000060208201529015156115395760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561087a578181015183820152602001610862565b50838360006115488383611454565b600160a060020a0316146040805190810160405280601481526020017f41434c5f4558495354454e545f4d414e414745520000000000000000000000008152509015156115da5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561087a578181015183820152602001610862565b50610cee87878787612069565b6115ef610d54565b60408051808201909152601881527f494e49545f414c52454144595f494e495449414c495a45440000000000000000602082015290156116745760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561087a578181015183820152602001610862565b5061167d61208e565b611685611744565b60408051808201909152601481527f41434c5f415554485f494e49545f4b45524e454c000000000000000000000000602082015290600160a060020a031633146117145760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561087a578181015183820152602001610862565b5061172f813060008051602061267783398151915282612069565b50565b60008051602061265783398151915281565b6000610d4f7f4172f0f7d2289153072b0a6ca36959e0cbe2efc3afe50fc81636caa96338137b611e00565b600060001961177c610d54565b14905090565b600181565b600080600080600061179a8989896118c4565b8152602081019190915260400160002054915081158015906117c457506117c48288888888610a84565b156117d25760019250611821565b6000806117e260001989896118c4565b81526020810191909152604001600020549050801580159061180e575061180e81600019888888610a84565b1561181c5760019250611821565b600092505b5050949350505050565b6000610ab685858561183c86612156565b611787565b4390565b82600260006118548585611fac565b8152602081019190915260409081016000908120805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a039485161790559051858316928492908616917ff3addc8b8e25ee11528a61b0e65092cae0666ef0ec0c64cb303993c88d689b4d9190a4505050565b604080517f5045524d495353494f4e00000000000000000000000000000000000000000000602080830191909152600160a060020a03808716606090811b602a850152908616901b603e8301526052808301859052835180840390910181526072909201928390528151600093918291908401908083835b6020831061195b5780518252601f19909201916020918201910161193c565b5181516020939093036101000a60001901801990911692169190911790526040519201829003909120979650505050505050565b6000611999612636565b600088815260016020526040812054819063ffffffff8a16106119bf5760009350611b6f565b60008a8152600160205260409020805463ffffffff8b169081106119df57fe5b600091825260209182902060408051606081018252929091015460ff808216808552610100830490911694840194909452620100009004600160f060020a031690820152935060cc1415611a4257611a3b838b8a8a8a8a612200565b9350611b6f565b5060408201518251600160f060020a039091169060ff1660cb1415611a8e57611a728360400151898989896123a5565b611a7d576000611a80565b60015b60ff16915060019050611b1e565b825160ff1660c81415611aaa57611aa3611841565b9150611b1e565b825160ff1660c91415611abf57611aa36124d7565b825160ff1660cd1415611ae1578260400151600160f060020a03169150611b1e565b8451835160ff1610611af65760009350611b6f565b82518551869160ff16908110611b0857fe5b90602001906020020151600160f060020a031691505b6007836020015160ff16600c811115611b3357fe5b600c811115611b3e57fe5b1415611b4f57600082119350611b6f565b611b6c82846020015160ff16600c811115611b6657fe5b836124db565b93505b5050509695505050505050565b6000806000806000611b8c612636565b8660405160200180828051906020019060200280838360005b83811015611bbd578181015183820152602001611ba5565b505050509050019150506040516020818303038152906040526040518082805190602001908083835b60208310611c055780518252601f199092019160209182019101611be6565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912060008181526001909252929020805492995097505015159150611d13905057600092505b8651831015611d13578683815181101515611c6857fe5b906020019060200201519150606060405190810160405280611c8984612598565b60ff168152602001611c9a8461259e565b60ff9081168252600160f060020a03858116602093840152875460018082018a5560008a815285902086519201805495870151604088015160ff199097169386169390931761ff00191661010093909516929092029390931761ffff166201000094909216939093021790915593909301929050611c51565b509295945050505050565b60008082600080611d308989896118c4565b81526020810191909152604001600020558215801592508290611d6157506000805160206126578339815191528314155b60408051841515815290519192508591600160a060020a0380891692908a16917f759b9a74d5354b5801710a0c1b283cc9f0d32b607ac8ced10c83ac8e75c77d529181900360200190a48015611df8576040805184815290518591600160a060020a0380891692908a16917f8dfee25d92d73b8c9b868f9fa3e215cc1981033f426e53803e3da4f09a2cfc30919081900360200190a45b505050505050565b5490565b5490565b600080600160a060020a0383161515611e245760009150611e2f565b823b90506000811191505b50919050565b60408051600160a060020a038316602480830191909152825180830390910181526044909101909152602081018051600160e060020a03167f70a08231000000000000000000000000000000000000000000000000000000001790526000908180611ea086846125a4565b60408051808201909152601c81527f534146455f4552435f32305f42414c414e43455f52455645525445440000000060208201529193509150821515611f2b5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561087a578181015183820152602001610862565b5095945050505050565b60408051600160a060020a03841660248201526044808201849052825180830390910181526064909101909152602081018051600160e060020a03167fa9059cbb00000000000000000000000000000000000000000000000000000000179052600090610d1385826125d5565b8051602002815290565b604080517f524f4c4500000000000000000000000000000000000000000000000000000000602080830191909152600160a060020a03851660601b60248301526038808301859052835180840390910181526058909201928390528151600093918291908401908083835b602083106120365780518252601f199092019160209182019101612017565b5181516020939093036101000a600019018019909116921691909117905260405192018290039091209695505050505050565b612083848484600080516020612657833981519152611d1e565b610a00818484611845565b612096610d54565b60408051808201909152601881527f494e49545f414c52454144595f494e495449414c495a454400000000000000006020820152901561211b5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561087a578181015183820152602001610862565b50612154612127611841565b7febb05b386a8d34882b8711d156f463690983dc47815980fb82aeeff1aa43579e9063ffffffff61262316565b565b606060006020835181151561216757fe5b049050806020028351146040805190810160405280601a81526020017f434f4e56455253494f4e5f494d50524f5045525f4c454e4754480000000000008152509015156121f95760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561087a578181015183820152602001610862565b5082525090565b60008080808080808080600c8f6020015160ff16600c81111561221f57fe5b600c81111561222a57fe5b141561227e576122468f60400151600160f060020a0316612627565b9199509750955061225b8e898f8f8f8f61198f565b94506122778e8661226c578761226e565b885b8f8f8f8f61198f565b9850612393565b6122948f60400151600160f060020a0316612627565b5090945092506122a88e858f8f8f8f61198f565b915060088f6020015160ff16600c8111156122bf57fe5b600c8111156122ca57fe5b14156122d95781159850612393565b8180156123035750600a8f6020015160ff16600c8111156122f657fe5b600c81111561230157fe5b145b156123115760019850612393565b8115801561233c575060098f6020015160ff16600c81111561232f57fe5b600c81111561233a57fe5b145b1561234a5760009850612393565b6123588e848f8f8f8f61198f565b9050600b8f6020015160ff16600c81111561236f57fe5b600c81111561237a57fe5b141561238f5780151582151514159850612393565b8098505b50505050505050509695505050505050565b604051600160a060020a0385811660248301908152908516604483015260648201849052608060848301908152835160a484015283516000937f2a151090000000000000000000000000000000000000000000000000000000009360609386938493849388938e938e938e938e939092909160c40190602080860191028083838d5b8381101561243f578181015183820152602001612427565b505050509050019550505050505060405160208183030381529060405290600160e060020a031916602082018051600160e060020a03838183161783525050505093506000808551602087018e5afa92508215156124a057600095506124c9565b3d9150602082146124b457600095506124c9565b604051826000823e8051915060008152508095505b505050505095945050505050565b4290565b6000600183600c8111156124eb57fe5b14156124fa5750828114610a7d565b600283600c81111561250857fe5b1415612518575082811415610a7d565b600383600c81111561252657fe5b14156125355750808311610a7d565b600483600c81111561254357fe5b14156125525750808310610a7d565b600583600c81111561256057fe5b1415612570575080831015610a7d565b600683600c81111561257e57fe5b141561258e575080831115610a7d565b5060009392505050565b60f81c90565b60f01c90565b6000806000806040516020818751602089018a5afa925060008311156125c957805191505b50909590945092505050565b6000806040516020818551602087016000895af16000811115612619573d8015612606576020811461260f57612617565b60019350612617565b600183511493505b505b5090949350505050565b9055565b90602082901c90604083901c90565b6040805160608101825260008082526020820181905291810191909152905600290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5630b719b33c83b8e5d300c521cb8b54ae9bd933996a14bef8c2f4e0285d2d2400a41434c5f415554485f4e4f5f4d414e4147455200000000000000000000000000a165627a7a72305820a4da4c95d7d8c2b1c741084cecd9cefb85a88288abb05b15d0c83f20377359050029ebb05b386a8d34882b8711d156f463690983dc47815980fb82aeeff1aa43579e
Deployed Bytecode
0x6080604052600436106101795760003560e01c63ffffffff1680630803fac01461017e5780630808343e146101a757806309699ff5146101cd5780630a8ed3db146101f157806315949ed71461021b5780631b5e75be146102575780631d63ff2b146102cc5780632914b9bd146102e157806332f0a3b5146103565780633d6ab68f1461036b5780636815c992146103805780636d6712d8146103f45780637e7db6e11461041e57806380afdea81461043f5780638b3dd749146104545780639d0effdb146104695780639d4941d814610493578063a03c5832146104b4578063a1658fad1461050e578063a479e50814610575578063a5ed8bf81461058a578063a885508a1461059f578063afd925df146105c3578063b1905727146105ed578063be03847814610611578063c4d66de814610642578063c513f66e14610663578063d4aae0c414610678578063de4796ed1461068d578063f516bc0e146106a2578063f520b58d146106b7578063fdef91061461072b575b600080fd5b34801561018a57600080fd5b5061019361079a565b604080519115158252519081900360200190f35b3480156101b357600080fd5b506101cb600160a060020a03600435166024356107c3565b005b3480156101d957600080fd5b506101cb600160a060020a036004351660243561096a565b3480156101fd57600080fd5b506101cb600160a060020a0360043581169060243516604435610a06565b34801561022757600080fd5b50610245600160a060020a0360043581169060243516604435610a42565b60408051918252519081900360200190f35b34801561026357600080fd5b5060408051602060046084358181013583810280860185019096528085526101939583359560248035600160a060020a039081169760443590911696606435963696919560a495949091019282919085019084908082843750949750610a849650505050505050565b3480156102d857600080fd5b50610245610abf565b3480156102ed57600080fd5b506040805160206004803580820135601f810184900484028501840190955284845261033a943694929360249392840191908190840183828082843750949750610ac49650505050505050565b60408051600160a060020a039092168252519081900360200190f35b34801561036257600080fd5b5061033a610ba7565b34801561037757600080fd5b50610245610c1c565b34801561038c57600080fd5b5060408051606435600481810135602081810285810182019096528185526101cb95600160a060020a0384358116966024803590921696604435963696909560849593949290920192909182919085019084908082843750949750610c2e9650505050505050565b34801561040057600080fd5b50610193600160a060020a0360043581169060243516604435610cf7565b34801561042a57600080fd5b50610193600160a060020a0360043516610d1e565b34801561044b57600080fd5b50610245610d24565b34801561046057600080fd5b50610245610d54565b34801561047557600080fd5b506101cb600160a060020a0360043581169060243516604435610d7f565b34801561049f57600080fd5b506101cb600160a060020a0360043516610e16565b3480156104c057600080fd5b506104e1600160a060020a03600435811690602435166044356064356110a5565b6040805160ff9485168152929093166020830152600160f060020a03168183015290519081900360600190f35b34801561051a57600080fd5b506040805160206004604435818101358381028086018501909652808552610193958335600160a060020a03169560248035963696956064959394920192918291850190849080828437509497506111239650505050505050565b34801561058157600080fd5b5061033a61126e565b34801561059657600080fd5b5061033a611323565b3480156105ab57600080fd5b506101cb600160a060020a0360043516602435611329565b3480156105cf57600080fd5b506101cb600160a060020a03600435811690602435166044356113bf565b3480156105f957600080fd5b5061033a600160a060020a0360043516602435611454565b34801561061d57600080fd5b506101cb600160a060020a036004358116906024358116906044359060643516611485565b34801561064e57600080fd5b506101cb600160a060020a03600435166115e7565b34801561066f57600080fd5b50610245611732565b34801561068457600080fd5b5061033a611744565b34801561069957600080fd5b5061019361176f565b3480156106ae57600080fd5b5061033a611782565b3480156106c357600080fd5b50604080516064356004818101356020818102858101820190965281855261019395600160a060020a03843581169660248035909216966044359636969095608495939492909201929091829190850190849080828437509497506117879650505050505050565b34801561073757600080fd5b50604080516020601f60643560048181013592830184900484028501840190955281845261019394600160a060020a03813581169560248035909216956044359536956084940191819084018382808284375094975061182b9650505050505050565b6000806107a5610d54565b905080158015906107bd5750806107ba611841565b10155b91505090565b60408051600080825260208201909252600080516020612677833981519152916107f39133918491905b50611123565b60408051808201909152600f81527f4150505f415554485f4641494c4544000000000000000000000000000000000060208201529015156108b55760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561087a578181015183820152602001610862565b50505050905090810190601f1680156108a75780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50828260006108c48383611454565b600160a060020a0316146040805190810160405280601481526020017f41434c5f4558495354454e545f4d414e414745520000000000000000000000008152509015156109565760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561087a578181015183820152602001610862565b5061096360018686611845565b5050505050565b81816109768282611454565b6040805180820190915260138152600080516020612697833981519152602082015290600160a060020a031633146109f35760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561087a578181015183820152602001610862565b50610a0060018585611845565b50505050565b610a3d8383836000604051908082528060200260200182016040528015610a37578160200160208202803883390190505b50610c2e565b505050565b600060016000806000610a568888886118c4565b81526020808201929092526040908101600090812054845291830193909352910190205490505b9392505050565b6000600080516020612657833981519152861415610aa457506001610ab6565b610ab38660008787878761198f565b90505b95945050505050565b600081565b6000610ace61126e565b600160a060020a03166304bf2a7f836040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610b29578181015183820152602001610b11565b50505050905090810190601f168015610b565780820380516001836020036101000a031916815260200191505b5092505050602060405180830381600087803b158015610b7557600080fd5b505af1158015610b89573d6000803e3d6000fd5b505050506040513d6020811015610b9f57600080fd5b505192915050565b6000610bb1611744565b600160a060020a03166332f0a3b56040518163ffffffff1660e01b8152600401602060405180830381600087803b158015610beb57600080fd5b505af1158015610bff573d6000803e3d6000fd5b505050506040513d6020811015610c1557600080fd5b5051905090565b60008051602061267783398151915281565b60008383610c3c8282611454565b6040805180820190915260138152600080516020612697833981519152602082015290600160a060020a03163314610cb95760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561087a578181015183820152602001610862565b506000845111610cd757600080516020612657833981519152610ce0565b610ce084611b7c565b9250610cee87878786611d1e565b50505050505050565b60408051600080825260208201909252610d1385858584611787565b91505b509392505050565b50600190565b6000610d4f7fd625496217aa6a3453eecb9c3489dc5a53e6c67b444329ea2b2cbc9ff547639b611e00565b905090565b6000610d4f7febb05b386a8d34882b8711d156f463690983dc47815980fb82aeeff1aa43579e611e00565b8181610d8b8282611454565b6040805180820190915260138152600080516020612697833981519152602082015290600160a060020a03163314610e085760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561087a578181015183820152602001610862565b506109638585856000611d1e565b6000806000610e2484610d1e565b60408051808201909152601281527f5245434f5645525f444953414c4c4f57454400000000000000000000000000006020820152901515610eaa5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561087a578181015183820152602001610862565b50610eb3610ba7565b9250610ebe83611e08565b60408051808201909152601a81527f5245434f5645525f5641554c545f4e4f545f434f4e54524143540000000000006020820152901515610f445760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561087a578181015183820152602001610862565b50600160a060020a0384161515610f955760405130319250600160a060020a0384169083156108fc029084906000818181858888f19350505050158015610f8f573d6000803e3d6000fd5b50611054565b5082610fb0600160a060020a0382163063ffffffff611e3516565b9150610fcc600160a060020a038216848463ffffffff611f3516565b60408051808201909152601d81527f5245434f5645525f544f4b454e5f5452414e534645525f4641494c454400000060208201529015156110525760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561087a578181015183820152602001610862565b505b83600160a060020a031683600160a060020a03167f596caf56044b55fb8c4ca640089bbc2b63cae3e978b851f5745cbb7c5b288e02846040518082815260200191505060405180910390a350505050565b600080600080600160008060006110bd8c8c8c6118c4565b81526020808201929092526040908101600090812054845291830193909352910190208054869081106110ec57fe5b60009182526020909120015460ff8082169a6101008304909116995062010000909104600160f060020a0316975095505050505050565b60008061112e61079a565b151561113d5760009150610d16565b611145611744565b9050600160a060020a03811615156111605760009150610d16565b80600160a060020a031663fdef910686308761117b88611fa2565b60405163ffffffff861660e01b8152600160a060020a03808616600483019081529085166024830152604482018490526080606483019081528351608484015283519192909160a490910190602085019080838360005b838110156111ea5781810151838201526020016111d2565b50505050905090810190601f1680156112175780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b15801561123957600080fd5b505af115801561124d573d6000803e3d6000fd5b505050506040513d602081101561126357600080fd5b505195945050505050565b600080611279611744565b604080517fbe00bbd80000000000000000000000000000000000000000000000000000000081527fd6f028ca0e8edb4a8c9757ca4fdccab25fa1e0317da1188108f7d2dee14902fb60048201527fddbcfd564f642ab5627cf68b9b7d374fb4f8a36e941a75d89c87998cef03bd6160248201529051600160a060020a03929092169163be00bbd8916044808201926020929091908290030181600087803b158015610b7557600080fd5b60001981565b81816113358282611454565b6040805180820190915260138152600080516020612697833981519152602082015290600160a060020a031633146113b25760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561087a578181015183820152602001610862565b50610a0060008585611845565b81816113cb8282611454565b6040805180820190915260138152600080516020612697833981519152602082015290600160a060020a031633146114485760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561087a578181015183820152602001610862565b50610963858585611845565b6000600260006114648585611fac565b8152602081019190915260400160002054600160a060020a03169392505050565b60408051600080825260208201909252600080516020612677833981519152916114b39133918491906107ed565b60408051808201909152600f81527f4150505f415554485f4641494c4544000000000000000000000000000000000060208201529015156115395760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561087a578181015183820152602001610862565b50838360006115488383611454565b600160a060020a0316146040805190810160405280601481526020017f41434c5f4558495354454e545f4d414e414745520000000000000000000000008152509015156115da5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561087a578181015183820152602001610862565b50610cee87878787612069565b6115ef610d54565b60408051808201909152601881527f494e49545f414c52454144595f494e495449414c495a45440000000000000000602082015290156116745760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561087a578181015183820152602001610862565b5061167d61208e565b611685611744565b60408051808201909152601481527f41434c5f415554485f494e49545f4b45524e454c000000000000000000000000602082015290600160a060020a031633146117145760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561087a578181015183820152602001610862565b5061172f813060008051602061267783398151915282612069565b50565b60008051602061265783398151915281565b6000610d4f7f4172f0f7d2289153072b0a6ca36959e0cbe2efc3afe50fc81636caa96338137b611e00565b600060001961177c610d54565b14905090565b600181565b600080600080600061179a8989896118c4565b8152602081019190915260400160002054915081158015906117c457506117c48288888888610a84565b156117d25760019250611821565b6000806117e260001989896118c4565b81526020810191909152604001600020549050801580159061180e575061180e81600019888888610a84565b1561181c5760019250611821565b600092505b5050949350505050565b6000610ab685858561183c86612156565b611787565b4390565b82600260006118548585611fac565b8152602081019190915260409081016000908120805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a039485161790559051858316928492908616917ff3addc8b8e25ee11528a61b0e65092cae0666ef0ec0c64cb303993c88d689b4d9190a4505050565b604080517f5045524d495353494f4e00000000000000000000000000000000000000000000602080830191909152600160a060020a03808716606090811b602a850152908616901b603e8301526052808301859052835180840390910181526072909201928390528151600093918291908401908083835b6020831061195b5780518252601f19909201916020918201910161193c565b5181516020939093036101000a60001901801990911692169190911790526040519201829003909120979650505050505050565b6000611999612636565b600088815260016020526040812054819063ffffffff8a16106119bf5760009350611b6f565b60008a8152600160205260409020805463ffffffff8b169081106119df57fe5b600091825260209182902060408051606081018252929091015460ff808216808552610100830490911694840194909452620100009004600160f060020a031690820152935060cc1415611a4257611a3b838b8a8a8a8a612200565b9350611b6f565b5060408201518251600160f060020a039091169060ff1660cb1415611a8e57611a728360400151898989896123a5565b611a7d576000611a80565b60015b60ff16915060019050611b1e565b825160ff1660c81415611aaa57611aa3611841565b9150611b1e565b825160ff1660c91415611abf57611aa36124d7565b825160ff1660cd1415611ae1578260400151600160f060020a03169150611b1e565b8451835160ff1610611af65760009350611b6f565b82518551869160ff16908110611b0857fe5b90602001906020020151600160f060020a031691505b6007836020015160ff16600c811115611b3357fe5b600c811115611b3e57fe5b1415611b4f57600082119350611b6f565b611b6c82846020015160ff16600c811115611b6657fe5b836124db565b93505b5050509695505050505050565b6000806000806000611b8c612636565b8660405160200180828051906020019060200280838360005b83811015611bbd578181015183820152602001611ba5565b505050509050019150506040516020818303038152906040526040518082805190602001908083835b60208310611c055780518252601f199092019160209182019101611be6565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912060008181526001909252929020805492995097505015159150611d13905057600092505b8651831015611d13578683815181101515611c6857fe5b906020019060200201519150606060405190810160405280611c8984612598565b60ff168152602001611c9a8461259e565b60ff9081168252600160f060020a03858116602093840152875460018082018a5560008a815285902086519201805495870151604088015160ff199097169386169390931761ff00191661010093909516929092029390931761ffff166201000094909216939093021790915593909301929050611c51565b509295945050505050565b60008082600080611d308989896118c4565b81526020810191909152604001600020558215801592508290611d6157506000805160206126578339815191528314155b60408051841515815290519192508591600160a060020a0380891692908a16917f759b9a74d5354b5801710a0c1b283cc9f0d32b607ac8ced10c83ac8e75c77d529181900360200190a48015611df8576040805184815290518591600160a060020a0380891692908a16917f8dfee25d92d73b8c9b868f9fa3e215cc1981033f426e53803e3da4f09a2cfc30919081900360200190a45b505050505050565b5490565b5490565b600080600160a060020a0383161515611e245760009150611e2f565b823b90506000811191505b50919050565b60408051600160a060020a038316602480830191909152825180830390910181526044909101909152602081018051600160e060020a03167f70a08231000000000000000000000000000000000000000000000000000000001790526000908180611ea086846125a4565b60408051808201909152601c81527f534146455f4552435f32305f42414c414e43455f52455645525445440000000060208201529193509150821515611f2b5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561087a578181015183820152602001610862565b5095945050505050565b60408051600160a060020a03841660248201526044808201849052825180830390910181526064909101909152602081018051600160e060020a03167fa9059cbb00000000000000000000000000000000000000000000000000000000179052600090610d1385826125d5565b8051602002815290565b604080517f524f4c4500000000000000000000000000000000000000000000000000000000602080830191909152600160a060020a03851660601b60248301526038808301859052835180840390910181526058909201928390528151600093918291908401908083835b602083106120365780518252601f199092019160209182019101612017565b5181516020939093036101000a600019018019909116921691909117905260405192018290039091209695505050505050565b612083848484600080516020612657833981519152611d1e565b610a00818484611845565b612096610d54565b60408051808201909152601881527f494e49545f414c52454144595f494e495449414c495a454400000000000000006020820152901561211b5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561087a578181015183820152602001610862565b50612154612127611841565b7febb05b386a8d34882b8711d156f463690983dc47815980fb82aeeff1aa43579e9063ffffffff61262316565b565b606060006020835181151561216757fe5b049050806020028351146040805190810160405280601a81526020017f434f4e56455253494f4e5f494d50524f5045525f4c454e4754480000000000008152509015156121f95760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360008381101561087a578181015183820152602001610862565b5082525090565b60008080808080808080600c8f6020015160ff16600c81111561221f57fe5b600c81111561222a57fe5b141561227e576122468f60400151600160f060020a0316612627565b9199509750955061225b8e898f8f8f8f61198f565b94506122778e8661226c578761226e565b885b8f8f8f8f61198f565b9850612393565b6122948f60400151600160f060020a0316612627565b5090945092506122a88e858f8f8f8f61198f565b915060088f6020015160ff16600c8111156122bf57fe5b600c8111156122ca57fe5b14156122d95781159850612393565b8180156123035750600a8f6020015160ff16600c8111156122f657fe5b600c81111561230157fe5b145b156123115760019850612393565b8115801561233c575060098f6020015160ff16600c81111561232f57fe5b600c81111561233a57fe5b145b1561234a5760009850612393565b6123588e848f8f8f8f61198f565b9050600b8f6020015160ff16600c81111561236f57fe5b600c81111561237a57fe5b141561238f5780151582151514159850612393565b8098505b50505050505050509695505050505050565b604051600160a060020a0385811660248301908152908516604483015260648201849052608060848301908152835160a484015283516000937f2a151090000000000000000000000000000000000000000000000000000000009360609386938493849388938e938e938e938e939092909160c40190602080860191028083838d5b8381101561243f578181015183820152602001612427565b505050509050019550505050505060405160208183030381529060405290600160e060020a031916602082018051600160e060020a03838183161783525050505093506000808551602087018e5afa92508215156124a057600095506124c9565b3d9150602082146124b457600095506124c9565b604051826000823e8051915060008152508095505b505050505095945050505050565b4290565b6000600183600c8111156124eb57fe5b14156124fa5750828114610a7d565b600283600c81111561250857fe5b1415612518575082811415610a7d565b600383600c81111561252657fe5b14156125355750808311610a7d565b600483600c81111561254357fe5b14156125525750808310610a7d565b600583600c81111561256057fe5b1415612570575080831015610a7d565b600683600c81111561257e57fe5b141561258e575080831115610a7d565b5060009392505050565b60f81c90565b60f01c90565b6000806000806040516020818751602089018a5afa925060008311156125c957805191505b50909590945092505050565b6000806040516020818551602087016000895af16000811115612619573d8015612606576020811461260f57612617565b60019350612617565b600183511493505b505b5090949350505050565b9055565b90602082901c90604083901c90565b6040805160608101825260008082526020820181905291810191909152905600290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5630b719b33c83b8e5d300c521cb8b54ae9bd933996a14bef8c2f4e0285d2d2400a41434c5f415554485f4e4f5f4d414e4147455200000000000000000000000000a165627a7a72305820a4da4c95d7d8c2b1c741084cecd9cefb85a88288abb05b15d0c83f20377359050029
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.