Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x60806040 | 16937815 | 586 days ago | IN | 0 ETH | 0.07320879 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
InstanceService
Compiler Version
v0.8.2+commit.661d1103
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.2; import "ComponentController.sol"; import "BundleController.sol"; import "PolicyController.sol"; import "PoolController.sol"; import "TreasuryModule.sol"; import "CoreController.sol"; import "InstanceOperatorService.sol"; import "IComponent.sol"; import "IOracle.sol"; import "IProduct.sol"; import "IRiskpool.sol"; import "IPolicy.sol"; import "IRegistry.sol"; import "IComponentOwnerService.sol"; import "IInstanceService.sol"; import "IInstanceOperatorService.sol"; import "IOracleService.sol"; import "IProductService.sol"; import "IRiskpoolService.sol"; import "IBundleToken.sol"; import "IERC20.sol"; import "IERC721.sol"; contract InstanceService is IInstanceService, CoreController { bytes32 public constant BUNDLE_NAME = "Bundle"; bytes32 public constant COMPONENT_NAME = "Component"; bytes32 public constant POLICY_NAME = "Policy"; bytes32 public constant POOL_NAME = "Pool"; bytes32 public constant TREASURY_NAME = "Treasury"; bytes32 public constant COMPONENT_OWNER_SERVICE_NAME = "ComponentOwnerService"; bytes32 public constant INSTANCE_OPERATOR_SERVICE_NAME = "InstanceOperatorService"; bytes32 public constant ORACLE_SERVICE_NAME = "OracleService"; bytes32 public constant PRODUCT_SERVICE_NAME = "ProductService"; bytes32 public constant RISKPOOL_SERVICE_NAME = "RiskpoolService"; BundleController _bundle; ComponentController _component; PolicyController _policy; PoolController _pool; TreasuryModule private _treasury; mapping(uint256 /* chain id */ => string /* chain name */) private _chainName; function _afterInitialize() internal override onlyInitializing { _bundle = BundleController(_getContractAddress(BUNDLE_NAME)); _component = ComponentController(_getContractAddress(COMPONENT_NAME)); _policy = PolicyController(_getContractAddress(POLICY_NAME)); _pool = PoolController(_getContractAddress(POOL_NAME)); _treasury = TreasuryModule(_getContractAddress(TREASURY_NAME)); _setChainNames(); } function _setChainNames() internal { _chainName[1] = "Ethereum Mainnet/ETH"; _chainName[5] = "Goerli/ETH"; _chainName[1337] = "Ganache"; _chainName[100] = "Gnosis/xDai"; _chainName[77] = "Sokol/SPOA"; _chainName[137] = "Polygon Mainnet/MATIC"; _chainName[8001] = "Mumbai/MATIC"; _chainName[43114] = "Avalanche C-Chain/AVAX"; _chainName[43113] = "Avalanche Fuji Testnet/AVAX"; } /* instance service */ function getChainId() public override view returns(uint256 chainId) { chainId = block.chainid; } function getChainName() public override view returns(string memory chainName) { chainName = _chainName[block.chainid]; } function getInstanceId() public override view returns(bytes32 instanceId) { instanceId = keccak256( abi.encodePacked( block.chainid, address(_registry))); } function getInstanceOperator() external override view returns(address) { InstanceOperatorService ios = InstanceOperatorService(_getContractAddress(INSTANCE_OPERATOR_SERVICE_NAME)); return ios.owner(); } /* registry */ function getComponentOwnerService() external override view returns(IComponentOwnerService service) { return IComponentOwnerService(_getContractAddress(COMPONENT_OWNER_SERVICE_NAME)); } function getInstanceOperatorService() external override view returns(IInstanceOperatorService service) { return IInstanceOperatorService(_getContractAddress(INSTANCE_OPERATOR_SERVICE_NAME)); } function getOracleService() external override view returns(IOracleService service) { return IOracleService(_getContractAddress(ORACLE_SERVICE_NAME)); } function getProductService() external override view returns(IProductService service) { return IProductService(_getContractAddress(PRODUCT_SERVICE_NAME)); } function getRiskpoolService() external override view returns(IRiskpoolService service) { return IRiskpoolService(_getContractAddress(RISKPOOL_SERVICE_NAME)); } /* registry */ function getRegistry() external view returns(IRegistry service) { return _registry; } function contracts() external view override returns (uint256 numberOfContracts) { numberOfContracts = _registry.contracts(); } function contractName(uint256 idx) external view override returns (bytes32 name) { name = _registry.contractName(idx); } /* access */ function getDefaultAdminRole() external override view returns(bytes32) { return _access.getDefaultAdminRole(); } function getProductOwnerRole() external override view returns(bytes32) { return _access.getProductOwnerRole(); } function getOracleProviderRole() external override view returns(bytes32) { return _access.getOracleProviderRole(); } function getRiskpoolKeeperRole() external override view returns(bytes32) { return _access.getRiskpoolKeeperRole(); } function hasRole(bytes32 role, address principal) external override view returns(bool) { return _access.hasRole(role, principal); } /* component */ function products() external override view returns(uint256) { return _component.products(); } function oracles() external override view returns(uint256) { return _component.oracles(); } function riskpools() external override view returns(uint256) { return _component.riskpools(); } function getComponentId(address componentAddress) external override view returns(uint256 componentId) { return _component.getComponentId(componentAddress); } function getComponentType(uint256 componentId) external override view returns(IComponent.ComponentType componentType) { return _component.getComponentType(componentId); } function getComponentState(uint256 componentId) external override view returns(IComponent.ComponentState componentState) { componentState = _component.getComponentState(componentId); } function getComponent(uint256 id) external override view returns(IComponent) { return _component.getComponent(id); } function getOracleId(uint256 idx) public view returns (uint256 oracleId) { return _component.getOracleId(idx); } function getRiskpoolId(uint256 idx) public view returns (uint256 riskpoolId) { return _component.getRiskpoolId(idx); } function getProductId(uint256 idx) public view returns (uint256 productId) { return _component.getProductId(idx); } /* service staking */ function getStakingRequirements(uint256 id) external override pure returns(bytes memory data) { revert("ERROR:IS-001:IMPLEMENATION_MISSING"); } function getStakedAssets(uint256 id) external override pure returns(bytes memory data) { revert("ERROR:IS-002:IMPLEMENATION_MISSING"); } /* policy */ function processIds() external override view returns(uint256 numberOfProcessIds) { numberOfProcessIds = _policy.processIds(); } function getMetadata(bytes32 bpKey) external override view returns(IPolicy.Metadata memory metadata) { metadata = _policy.getMetadata(bpKey); } function getApplication(bytes32 processId) external override view returns(IPolicy.Application memory application) { application = _policy.getApplication(processId); } function getPolicy(bytes32 processId) external override view returns(IPolicy.Policy memory policy) { policy = _policy.getPolicy(processId); } function claims(bytes32 processId) external override view returns(uint256 numberOfClaims) { numberOfClaims = _policy.getNumberOfClaims(processId); } function payouts(bytes32 processId) external override view returns(uint256 numberOfPayouts) { numberOfPayouts = _policy.getNumberOfPayouts(processId); } function getClaim(bytes32 processId, uint256 claimId) external override view returns (IPolicy.Claim memory claim) { claim = _policy.getClaim(processId, claimId); } function getPayout(bytes32 processId, uint256 payoutId) external override view returns (IPolicy.Payout memory payout) { payout = _policy.getPayout(processId, payoutId); } /* riskpool */ function getRiskpool(uint256 riskpoolId) external override view returns(IPool.Pool memory riskPool) { return _pool.getRiskpool(riskpoolId); } function getFullCollateralizationLevel() external override view returns (uint256) { return _pool.getFullCollateralizationLevel(); } function getCapital(uint256 riskpoolId) external override view returns(uint256 capitalAmount) { return _pool.getRiskpool(riskpoolId).capital; } function getTotalValueLocked(uint256 riskpoolId) external override view returns(uint256 totalValueLockedAmount) { return _pool.getRiskpool(riskpoolId).lockedCapital; } function getCapacity(uint256 riskpoolId) external override view returns(uint256 capacityAmount) { IPool.Pool memory pool = _pool.getRiskpool(riskpoolId); return pool.capital - pool.lockedCapital; } function getBalance(uint256 riskpoolId) external override view returns(uint256 balanceAmount) { return _pool.getRiskpool(riskpoolId).balance; } function activeBundles(uint256 riskpoolId) external override view returns(uint256 numberOfActiveBundles) { return _pool.activeBundles(riskpoolId); } function getActiveBundleId(uint256 riskpoolId, uint256 bundleIdx) external override view returns(uint256 bundleId) { return _pool.getActiveBundleId(riskpoolId, bundleIdx); } function getMaximumNumberOfActiveBundles(uint256 riskpoolId) external override view returns(uint256 maximumNumberOfActiveBundles) { return _pool.getMaximumNumberOfActiveBundles(riskpoolId); } /* bundle */ function getBundleToken() external override view returns(IBundleToken token) { BundleToken bundleToken = _bundle.getToken(); token = IBundleToken(bundleToken); } function getBundle(uint256 bundleId) external override view returns (IBundle.Bundle memory bundle) { bundle = _bundle.getBundle(bundleId); } function bundles() external override view returns (uint256) { return _bundle.bundles(); } function unburntBundles(uint256 riskpoolId) external override view returns(uint256 numberOfUnburntBundles) { numberOfUnburntBundles = _bundle.unburntBundles(riskpoolId); } /* treasury */ function getTreasuryAddress() external override view returns(address) { return address(_treasury); } function getInstanceWallet() external override view returns(address) { return _treasury.getInstanceWallet(); } function getRiskpoolWallet(uint256 riskpoolId) external override view returns(address) { return _treasury.getRiskpoolWallet(riskpoolId); } function getComponentToken(uint256 componentId) external override view returns(IERC20) { return _treasury.getComponentToken(componentId); } function getFeeFractionFullUnit() external override view returns(uint256) { return _treasury.getFractionFullUnit(); } }
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.2; import "CoreController.sol"; import "IComponent.sol"; import "IOracle.sol"; import "IProduct.sol"; import "IRiskpool.sol"; import "IComponentEvents.sol"; import "EnumerableSet.sol"; contract ComponentController is IComponentEvents, CoreController { using EnumerableSet for EnumerableSet.UintSet; mapping(uint256 => IComponent) private _componentById; mapping(bytes32 => uint256) private _componentIdByName; mapping(address => uint256) private _componentIdByAddress; mapping(uint256 => IComponent.ComponentState) private _componentState; EnumerableSet.UintSet private _products; EnumerableSet.UintSet private _oracles; EnumerableSet.UintSet private _riskpools; uint256 private _componentCount; mapping(uint256 /* product id */ => address /* policy flow address */) private _policyFlowByProductId; modifier onlyComponentOwnerService() { require( _msgSender() == _getContractAddress("ComponentOwnerService"), "ERROR:CCR-001:NOT_COMPONENT_OWNER_SERVICE"); _; } modifier onlyInstanceOperatorService() { require( _msgSender() == _getContractAddress("InstanceOperatorService"), "ERROR:CCR-002:NOT_INSTANCE_OPERATOR_SERVICE"); _; } function propose(IComponent component) external onlyComponentOwnerService { // input validation require(_componentIdByAddress[address(component)] == 0, "ERROR:CCR-003:COMPONENT_ALREADY_EXISTS"); require(_componentIdByName[component.getName()] == 0, "ERROR:CCR-004:COMPONENT_NAME_ALREADY_EXISTS"); // assigning id and persisting component uint256 id = _persistComponent(component); // log entry for successful proposal emit LogComponentProposed( component.getName(), component.getType(), address(component), id); // inform component about successful proposal component.proposalCallback(); } function _persistComponent(IComponent component) internal returns(uint256 id) { // fetch next component id _componentCount++; id = _componentCount; // update component state _changeState(id, IComponent.ComponentState.Proposed); component.setId(id); // update controller book keeping _componentById[id] = component; _componentIdByName[component.getName()] = id; _componentIdByAddress[address(component)] = id; // type specific book keeping if (component.isProduct()) { EnumerableSet.add(_products, id); } else if (component.isOracle()) { EnumerableSet.add(_oracles, id); } else if (component.isRiskpool()) { EnumerableSet.add(_riskpools, id); } } function exists(uint256 id) public view returns(bool) { IComponent component = _componentById[id]; return (address(component) != address(0)); } function approve(uint256 id) external onlyInstanceOperatorService { _changeState(id, IComponent.ComponentState.Active); IComponent component = getComponent(id); if (isProduct(id)) { _policyFlowByProductId[id] = IProduct(address(component)).getPolicyFlow(); } emit LogComponentApproved(id); // inform component about successful approval component.approvalCallback(); } function decline(uint256 id) external onlyInstanceOperatorService { _changeState(id, IComponent.ComponentState.Declined); emit LogComponentDeclined(id); // inform component about decline IComponent component = getComponent(id); component.declineCallback(); } function suspend(uint256 id) external onlyInstanceOperatorService { _changeState(id, IComponent.ComponentState.Suspended); emit LogComponentSuspended(id); // inform component about suspending IComponent component = getComponent(id); component.suspendCallback(); } function resume(uint256 id) external onlyInstanceOperatorService { _changeState(id, IComponent.ComponentState.Active); emit LogComponentResumed(id); // inform component about resuming IComponent component = getComponent(id); component.resumeCallback(); } function pause(uint256 id) external onlyComponentOwnerService { _changeState(id, IComponent.ComponentState.Paused); emit LogComponentPaused(id); // inform component about pausing IComponent component = getComponent(id); component.pauseCallback(); } function unpause(uint256 id) external onlyComponentOwnerService { _changeState(id, IComponent.ComponentState.Active); emit LogComponentUnpaused(id); // inform component about unpausing IComponent component = getComponent(id); component.unpauseCallback(); } function archiveFromComponentOwner(uint256 id) external onlyComponentOwnerService { _changeState(id, IComponent.ComponentState.Archived); emit LogComponentArchived(id); // inform component about archiving IComponent component = getComponent(id); component.archiveCallback(); } function archiveFromInstanceOperator(uint256 id) external onlyInstanceOperatorService { _changeState(id, IComponent.ComponentState.Archived); emit LogComponentArchived(id); // inform component about archiving IComponent component = getComponent(id); component.archiveCallback(); } function getComponent(uint256 id) public view returns (IComponent component) { component = _componentById[id]; require(address(component) != address(0), "ERROR:CCR-005:INVALID_COMPONENT_ID"); } function getComponentId(address componentAddress) public view returns (uint256 id) { require(componentAddress != address(0), "ERROR:CCR-006:COMPONENT_ADDRESS_ZERO"); id = _componentIdByAddress[componentAddress]; require(id > 0, "ERROR:CCR-007:COMPONENT_UNKNOWN"); } function getComponentType(uint256 id) public view returns (IComponent.ComponentType componentType) { if (EnumerableSet.contains(_products, id)) { return IComponent.ComponentType.Product; } else if (EnumerableSet.contains(_oracles, id)) { return IComponent.ComponentType.Oracle; } else if (EnumerableSet.contains(_riskpools, id)) { return IComponent.ComponentType.Riskpool; } else { revert("ERROR:CCR-008:INVALID_COMPONENT_ID"); } } function getComponentState(uint256 id) public view returns (IComponent.ComponentState componentState) { return _componentState[id]; } function getOracleId(uint256 idx) public view returns (uint256 oracleId) { return EnumerableSet.at(_oracles, idx); } function getRiskpoolId(uint256 idx) public view returns (uint256 riskpoolId) { return EnumerableSet.at(_riskpools, idx); } function getProductId(uint256 idx) public view returns (uint256 productId) { return EnumerableSet.at(_products, idx); } function getRequiredRole(IComponent.ComponentType componentType) external view returns (bytes32) { if (componentType == IComponent.ComponentType.Product) { return _access.getProductOwnerRole(); } else if (componentType == IComponent.ComponentType.Oracle) { return _access.getOracleProviderRole(); } else if (componentType == IComponent.ComponentType.Riskpool) { return _access.getRiskpoolKeeperRole(); } else { revert("ERROR:CCR-010:COMPONENT_TYPE_UNKNOWN"); } } function components() public view returns (uint256 count) { return _componentCount; } function products() public view returns (uint256 count) { return EnumerableSet.length(_products); } function oracles() public view returns (uint256 count) { return EnumerableSet.length(_oracles); } function riskpools() public view returns (uint256 count) { return EnumerableSet.length(_riskpools); } function isProduct(uint256 id) public view returns (bool) { return EnumerableSet.contains(_products, id); } function isOracle(uint256 id) public view returns (bool) { return EnumerableSet.contains(_oracles, id); } function isRiskpool(uint256 id) public view returns (bool) { return EnumerableSet.contains(_riskpools, id); } function getPolicyFlow(uint256 productId) public view returns (address _policyFlow) { require(isProduct(productId), "ERROR:CCR-011:UNKNOWN_PRODUCT_ID"); _policyFlow = _policyFlowByProductId[productId]; } function _changeState(uint256 componentId, IComponent.ComponentState newState) internal { IComponent.ComponentState oldState = _componentState[componentId]; _checkStateTransition(oldState, newState); _componentState[componentId] = newState; // log entry for successful component state change emit LogComponentStateChanged(componentId, oldState, newState); } function _checkStateTransition( IComponent.ComponentState oldState, IComponent.ComponentState newState ) internal pure { require(newState != oldState, "ERROR:CCR-020:SOURCE_AND_TARGET_STATE_IDENTICAL"); if (oldState == IComponent.ComponentState.Created) { require(newState == IComponent.ComponentState.Proposed, "ERROR:CCR-021:CREATED_INVALID_TRANSITION"); } else if (oldState == IComponent.ComponentState.Proposed) { require(newState == IComponent.ComponentState.Active || newState == IComponent.ComponentState.Declined, "ERROR:CCR-22:PROPOSED_INVALID_TRANSITION"); } else if (oldState == IComponent.ComponentState.Declined) { revert("ERROR:CCR-023:DECLINED_IS_FINAL_STATE"); } else if (oldState == IComponent.ComponentState.Active) { require(newState == IComponent.ComponentState.Paused || newState == IComponent.ComponentState.Suspended, "ERROR:CCR-024:ACTIVE_INVALID_TRANSITION"); } else if (oldState == IComponent.ComponentState.Paused) { require(newState == IComponent.ComponentState.Active || newState == IComponent.ComponentState.Archived, "ERROR:CCR-025:PAUSED_INVALID_TRANSITION"); } else if (oldState == IComponent.ComponentState.Suspended) { require(newState == IComponent.ComponentState.Active || newState == IComponent.ComponentState.Archived, "ERROR:CCR-026:SUSPENDED_INVALID_TRANSITION"); } else { revert("ERROR:CCR-027:INITIAL_STATE_NOT_HANDLED"); } } }
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.2; import "IAccess.sol"; import "IRegistry.sol"; import "Initializable.sol"; import "Context.sol"; contract CoreController is Context, Initializable { IRegistry internal _registry; IAccess internal _access; constructor () { _disableInitializers(); } modifier onlyInstanceOperator() { require( _registry.ensureSender(_msgSender(), "InstanceOperatorService"), "ERROR:CRC-001:NOT_INSTANCE_OPERATOR"); _; } modifier onlyPolicyFlow(bytes32 module) { // Allow only from delegator require( address(this) == _getContractAddress(module), "ERROR:CRC-002:NOT_ON_STORAGE" ); // Allow only ProductService (it delegates to PolicyFlow) require( _msgSender() == _getContractAddress("ProductService"), "ERROR:CRC-003:NOT_PRODUCT_SERVICE" ); _; } function initialize(address registry) public initializer { _registry = IRegistry(registry); if (_getName() != "Access") { _access = IAccess(_getContractAddress("Access")); } _afterInitialize(); } function _getName() internal virtual pure returns(bytes32) { return ""; } function _afterInitialize() internal virtual onlyInitializing {} function _getContractAddress(bytes32 contractName) internal view returns (address contractAddress) { contractAddress = _registry.getContract(contractName); require( contractAddress != address(0), "ERROR:CRC-004:CONTRACT_NOT_REGISTERED" ); } }
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.2; interface IAccess { function getDefaultAdminRole() external view returns(bytes32 role); function getProductOwnerRole() external view returns(bytes32 role); function getOracleProviderRole() external view returns(bytes32 role); function getRiskpoolKeeperRole() external view returns(bytes32 role); function hasRole(bytes32 role, address principal) external view returns(bool); function grantRole(bytes32 role, address principal) external; function revokeRole(bytes32 role, address principal) external; function renounceRole(bytes32 role, address principal) external; function addRole(bytes32 role) external; function invalidateRole(bytes32 role) external; }
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.2; interface IRegistry { event LogContractRegistered( bytes32 release, bytes32 contractName, address contractAddress, bool isNew ); event LogContractDeregistered(bytes32 release, bytes32 contractName); event LogReleasePrepared(bytes32 release); function registerInRelease( bytes32 _release, bytes32 _contractName, address _contractAddress ) external; function register(bytes32 _contractName, address _contractAddress) external; function deregisterInRelease(bytes32 _release, bytes32 _contractName) external; function deregister(bytes32 _contractName) external; function prepareRelease(bytes32 _newRelease) external; function getContractInRelease(bytes32 _release, bytes32 _contractName) external view returns (address _contractAddress); function getContract(bytes32 _contractName) external view returns (address _contractAddress); function getRelease() external view returns (bytes32 _release); function ensureSender(address sender, bytes32 _contractName) external view returns(bool _senderMatches); function contracts() external view returns (uint256 _numberOfContracts); function contractName(uint256 idx) external view returns (bytes32 _contractName); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; import "Address.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ``` * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!Address.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original * initialization step. This is essential to configure modules that are added through upgrades and that require * initialization. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized < type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.2; import "IRegistry.sol"; interface IComponent { enum ComponentType { Oracle, Product, Riskpool } enum ComponentState { Created, Proposed, Declined, Active, Paused, Suspended, Archived } event LogComponentCreated ( bytes32 componentName, IComponent.ComponentType componentType, address componentAddress, address registryAddress); function setId(uint256 id) external; function getName() external view returns(bytes32); function getId() external view returns(uint256); function getType() external view returns(ComponentType); function getState() external view returns(ComponentState); function getOwner() external view returns(address); function isProduct() external view returns(bool); function isOracle() external view returns(bool); function isRiskpool() external view returns(bool); function getRegistry() external view returns(IRegistry); function proposalCallback() external; function approvalCallback() external; function declineCallback() external; function suspendCallback() external; function resumeCallback() external; function pauseCallback() external; function unpauseCallback() external; function archiveCallback() external; }
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.2; import "IComponent.sol"; interface IOracle is IComponent { event LogOracleCreated (address oracleAddress); event LogOracleProposed (uint256 componentId); event LogOracleApproved (uint256 componentId); event LogOracleDeclined (uint256 componentId); function request(uint256 requestId, bytes calldata input) external; function cancel(uint256 requestId) external; }
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.2; import "IComponent.sol"; interface IProduct is IComponent { event LogProductCreated (address productAddress); event LogProductProposed (uint256 componentId); event LogProductApproved (uint256 componentId); event LogProductDeclined (uint256 componentId); function getToken() external view returns(address token); function getPolicyFlow() external view returns(address policyFlow); function getRiskpoolId() external view returns(uint256 riskpoolId); function getApplicationDataStructure() external view returns(string memory dataStructure); function getClaimDataStructure() external view returns(string memory dataStructure); function getPayoutDataStructure() external view returns(string memory dataStructure); function riskPoolCapacityCallback(uint256 capacity) external; }
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.2; import "IComponent.sol"; import "IBundle.sol"; import "IPolicy.sol"; interface IRiskpool is IComponent { event LogRiskpoolCreated (address riskpoolAddress); event LogRiskpoolProposed (uint256 id); event LogRiskpoolApproved (uint256 id); event LogRiskpoolDeclined (uint256 id); event LogRiskpoolBundleCreated(uint256 bundleId, uint256 amount); event LogRiskpoolBundleMatchesPolicy(uint256 bundleId, bool isMatching); event LogRiskpoolCollateralLocked(bytes32 processId, uint256 collateralAmount, bool isSecured); event LogRiskpoolPremiumProcessed(bytes32 processId, uint256 amount); event LogRiskpoolPayoutProcessed(bytes32 processId, uint256 amount); event LogRiskpoolCollateralReleased(bytes32 processId, uint256 collateralAmount); function createBundle(bytes memory filter, uint256 initialAmount) external returns(uint256 bundleId); function fundBundle(uint256 bundleId, uint256 amount) external returns(uint256 netAmount); function defundBundle(uint256 bundleId, uint256 amount) external returns(uint256 netAmount); function lockBundle(uint256 bundleId) external; function unlockBundle(uint256 bundleId) external; function closeBundle(uint256 bundleId) external; function burnBundle(uint256 bundleId) external; function collateralizePolicy(bytes32 processId, uint256 collateralAmount) external returns(bool isSecured); function processPolicyPremium(bytes32 processId, uint256 amount) external; function processPolicyPayout(bytes32 processId, uint256 amount) external; function releasePolicy(bytes32 processId) external; function getCollateralizationLevel() external view returns (uint256); function getFullCollateralizationLevel() external view returns (uint256); function bundleMatchesApplication( IBundle.Bundle memory bundle, IPolicy.Application memory application ) external view returns(bool isMatching); function getFilterDataStructure() external view returns(string memory); function bundles() external view returns(uint256); function getBundle(uint256 idx) external view returns(IBundle.Bundle memory); function activeBundles() external view returns(uint256); function getActiveBundleId(uint256 idx) external view returns(uint256 bundleId); function getWallet() external view returns(address); function getErc20Token() external view returns(address); function getSumOfSumInsuredCap() external view returns (uint256); function getCapital() external view returns(uint256); function getTotalValueLocked() external view returns(uint256); function getCapacity() external view returns(uint256); function getBalance() external view returns(uint256); function setMaximumNumberOfActiveBundles(uint256 maximumNumberOfActiveBundles) external; function getMaximumNumberOfActiveBundles() external view returns(uint256 maximumNumberOfActiveBundles); }
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.2; interface IBundle { event LogBundleCreated( uint256 bundleId, uint256 riskpoolId, address owner, BundleState state, uint256 amount ); event LogBundleStateChanged(uint256 bundleId, BundleState oldState, BundleState newState); event LogBundleCapitalProvided(uint256 bundleId, address sender, uint256 amount, uint256 capacity); event LogBundleCapitalWithdrawn(uint256 bundleId, address recipient, uint256 amount, uint256 capacity); event LogBundlePolicyCollateralized(uint256 bundleId, bytes32 processId, uint256 amount, uint256 capacity); event LogBundlePayoutProcessed(uint256 bundleId, bytes32 processId, uint256 amount); event LogBundlePolicyReleased(uint256 bundleId, bytes32 processId, uint256 amount, uint256 capacity); enum BundleState { Active, Locked, Closed, Burned } struct Bundle { uint256 id; uint256 riskpoolId; uint256 tokenId; BundleState state; bytes filter; // required conditions for applications to be considered for collateralization by this bundle uint256 capital; // net investment capital amount (<= balance) uint256 lockedCapital; // capital amount linked to collateralizaion of non-closed policies (<= capital) uint256 balance; // total amount of funds: net investment capital + net premiums - payouts uint256 createdAt; uint256 updatedAt; } function create(address owner_, uint256 riskpoolId_, bytes calldata filter_, uint256 amount_) external returns(uint256 bundleId); function fund(uint256 bundleId, uint256 amount) external; function defund(uint256 bundleId, uint256 amount) external; function lock(uint256 bundleId) external; function unlock(uint256 bundleId) external; function close(uint256 bundleId) external; function burn(uint256 bundleId) external; function collateralizePolicy(uint256 bundleId, bytes32 processId, uint256 collateralAmount) external; function processPremium(uint256 bundleId, bytes32 processId, uint256 amount) external; function processPayout(uint256 bundleId, bytes32 processId, uint256 amount) external; function releasePolicy(uint256 bundleId, bytes32 processId) external returns(uint256 collateralAmount); }
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.2; interface IPolicy { // Events event LogMetadataCreated( address owner, bytes32 processId, uint256 productId, PolicyFlowState state ); event LogMetadataStateChanged( bytes32 processId, PolicyFlowState state ); event LogApplicationCreated( bytes32 processId, uint256 premiumAmount, uint256 sumInsuredAmount ); event LogApplicationRevoked(bytes32 processId); event LogApplicationUnderwritten(bytes32 processId); event LogApplicationDeclined(bytes32 processId); event LogPolicyCreated(bytes32 processId); event LogPolicyExpired(bytes32 processId); event LogPolicyClosed(bytes32 processId); event LogPremiumCollected(bytes32 processId, uint256 amount); event LogApplicationSumInsuredAdjusted(bytes32 processId, uint256 sumInsuredAmountOld, uint256 sumInsuredAmount); event LogApplicationPremiumAdjusted(bytes32 processId, uint256 premiumAmountOld, uint256 premiumAmount); event LogPolicyPremiumAdjusted(bytes32 processId, uint256 premiumExpectedAmountOld, uint256 premiumExpectedAmount); event LogClaimCreated(bytes32 processId, uint256 claimId, uint256 claimAmount); event LogClaimConfirmed(bytes32 processId, uint256 claimId, uint256 confirmedAmount); event LogClaimDeclined(bytes32 processId, uint256 claimId); event LogClaimClosed(bytes32 processId, uint256 claimId); event LogPayoutCreated( bytes32 processId, uint256 claimId, uint256 payoutId, uint256 amount ); event LogPayoutProcessed( bytes32 processId, uint256 payoutId ); // States enum PolicyFlowState {Started, Active, Finished} enum ApplicationState {Applied, Revoked, Underwritten, Declined} enum PolicyState {Active, Expired, Closed} enum ClaimState {Applied, Confirmed, Declined, Closed} enum PayoutState {Expected, PaidOut} // Objects struct Metadata { address owner; uint256 productId; PolicyFlowState state; bytes data; uint256 createdAt; uint256 updatedAt; } struct Application { ApplicationState state; uint256 premiumAmount; uint256 sumInsuredAmount; bytes data; uint256 createdAt; uint256 updatedAt; } struct Policy { PolicyState state; uint256 premiumExpectedAmount; uint256 premiumPaidAmount; uint256 claimsCount; uint256 openClaimsCount; uint256 payoutMaxAmount; uint256 payoutAmount; uint256 createdAt; uint256 updatedAt; } struct Claim { ClaimState state; uint256 claimAmount; uint256 paidAmount; bytes data; uint256 createdAt; uint256 updatedAt; } struct Payout { uint256 claimId; PayoutState state; uint256 amount; bytes data; uint256 createdAt; uint256 updatedAt; } function createPolicyFlow( address owner, uint256 productId, bytes calldata data ) external returns(bytes32 processId); function createApplication( bytes32 processId, uint256 premiumAmount, uint256 sumInsuredAmount, bytes calldata data ) external; function revokeApplication(bytes32 processId) external; function underwriteApplication(bytes32 processId) external; function declineApplication(bytes32 processId) external; function collectPremium(bytes32 processId, uint256 amount) external; function adjustPremiumSumInsured( bytes32 processId, uint256 expectedPremiumAmount, uint256 sumInsuredAmount ) external; function createPolicy(bytes32 processId) external; function expirePolicy(bytes32 processId) external; function closePolicy(bytes32 processId) external; function createClaim( bytes32 processId, uint256 claimAmount, bytes calldata data ) external returns (uint256 claimId); function confirmClaim( bytes32 processId, uint256 claimId, uint256 confirmedAmount ) external; function declineClaim(bytes32 processId, uint256 claimId) external; function closeClaim(bytes32 processId, uint256 claimId) external; function createPayout( bytes32 processId, uint256 claimId, uint256 payoutAmount, bytes calldata data ) external returns (uint256 payoutId); function processPayout( bytes32 processId, uint256 payoutId ) external; }
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.2; import "IComponent.sol"; interface IComponentEvents { event LogComponentProposed ( bytes32 componentName, IComponent.ComponentType componentType, address componentAddress, uint256 id); event LogComponentApproved (uint256 id); event LogComponentDeclined (uint256 id); event LogComponentSuspended (uint256 id); event LogComponentResumed (uint256 id); event LogComponentPaused (uint256 id); event LogComponentUnpaused (uint256 id); event LogComponentArchived (uint256 id); event LogComponentStateChanged ( uint256 id, IComponent.ComponentState stateOld, IComponent.ComponentState stateNew); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol) pragma solidity ^0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. * * [WARNING] * ==== * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure unusable. * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. * * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an array of EnumerableSet. * ==== */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping(bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; if (lastIndex != toDeleteIndex) { bytes32 lastValue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastValue; // Update the index for the moved value set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex } // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { return set._values[index]; } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function _values(Set storage set) private view returns (bytes32[] memory) { return set._values; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { return _values(set._inner); } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(AddressSet storage set) internal view returns (address[] memory) { bytes32[] memory store = _values(set._inner); address[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values on the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(UintSet storage set) internal view returns (uint256[] memory) { bytes32[] memory store = _values(set._inner); uint256[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } }
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.2; import "PolicyController.sol"; import "CoreController.sol"; import "BundleToken.sol"; import "IProduct.sol"; import "IBundle.sol"; import "PoolController.sol"; contract BundleController is IBundle, CoreController { PolicyController private _policy; BundleToken private _token; mapping(uint256 /* bundleId */ => Bundle /* Bundle */) private _bundles; mapping(uint256 /* bundleId */ => uint256 /* activePolicyCount */) private _activePolicies; mapping(uint256 /* bundleId */ => mapping(bytes32 /* processId */ => uint256 /* lockedCapitalAmount */)) private _valueLockedPerPolicy; mapping(uint256 /* riskpoolId */ => uint256 /* numberOfUnburntBundles */) private _unburntBundlesForRiskpoolId; uint256 private _bundleCount; modifier onlyRiskpoolService() { require( _msgSender() == _getContractAddress("RiskpoolService"), "ERROR:BUC-001:NOT_RISKPOOL_SERVICE" ); _; } modifier onlyFundableBundle(uint256 bundleId) { Bundle storage bundle = _bundles[bundleId]; require(bundle.createdAt > 0, "ERROR:BUC-002:BUNDLE_DOES_NOT_EXIST"); require( bundle.state != IBundle.BundleState.Burned && bundle.state != IBundle.BundleState.Closed, "ERROR:BUC-003:BUNDLE_BURNED_OR_CLOSED" ); _; } function _afterInitialize() internal override onlyInitializing { _policy = PolicyController(_getContractAddress("Policy")); _token = BundleToken(_getContractAddress("BundleToken")); } function create(address owner_, uint riskpoolId_, bytes calldata filter_, uint256 amount_) external override onlyRiskpoolService returns(uint256 bundleId) { // will start with bundleId 1. // this helps in maps where a bundleId equals a non-existing entry bundleId = _bundleCount + 1; Bundle storage bundle = _bundles[bundleId]; require(bundle.createdAt == 0, "ERROR:BUC-010:BUNDLE_ALREADY_EXISTS"); // mint corresponding nft with bundleId as nft uint256 tokenId = _token.mint(bundleId, owner_); bundle.id = bundleId; bundle.tokenId = tokenId; bundle.riskpoolId = riskpoolId_; bundle.state = BundleState.Active; bundle.filter = filter_; bundle.capital = amount_; bundle.balance = amount_; bundle.createdAt = block.timestamp; bundle.updatedAt = block.timestamp; // update bundle count _bundleCount++; _unburntBundlesForRiskpoolId[riskpoolId_]++; emit LogBundleCreated(bundle.id, riskpoolId_, owner_, bundle.state, bundle.capital); } function fund(uint256 bundleId, uint256 amount) external override onlyRiskpoolService { Bundle storage bundle = _bundles[bundleId]; require(bundle.createdAt > 0, "ERROR:BUC-011:BUNDLE_DOES_NOT_EXIST"); require(bundle.state != IBundle.BundleState.Closed, "ERROR:BUC-012:BUNDLE_CLOSED"); bundle.capital += amount; bundle.balance += amount; bundle.updatedAt = block.timestamp; uint256 capacityAmount = bundle.capital - bundle.lockedCapital; emit LogBundleCapitalProvided(bundleId, _msgSender(), amount, capacityAmount); } function defund(uint256 bundleId, uint256 amount) external override onlyRiskpoolService { Bundle storage bundle = _bundles[bundleId]; require(bundle.createdAt > 0, "ERROR:BUC-013:BUNDLE_DOES_NOT_EXIST"); require( bundle.capital >= bundle.lockedCapital + amount || (bundle.lockedCapital == 0 && bundle.balance >= amount), "ERROR:BUC-014:CAPACITY_OR_BALANCE_TOO_LOW" ); if (bundle.capital >= amount) { bundle.capital -= amount; } else { bundle.capital = 0; } bundle.balance -= amount; bundle.updatedAt = block.timestamp; uint256 capacityAmount = bundle.capital - bundle.lockedCapital; emit LogBundleCapitalWithdrawn(bundleId, _msgSender(), amount, capacityAmount); } function lock(uint256 bundleId) external override onlyRiskpoolService { _changeState(bundleId, BundleState.Locked); } function unlock(uint256 bundleId) external override onlyRiskpoolService { _changeState(bundleId, BundleState.Active); } function close(uint256 bundleId) external override onlyRiskpoolService { require(_activePolicies[bundleId] == 0, "ERROR:BUC-015:BUNDLE_WITH_ACTIVE_POLICIES"); _changeState(bundleId, BundleState.Closed); } function burn(uint256 bundleId) external override onlyRiskpoolService { Bundle storage bundle = _bundles[bundleId]; require(bundle.state == BundleState.Closed, "ERROR:BUC-016:BUNDLE_NOT_CLOSED"); require(bundle.balance == 0, "ERROR:BUC-017:BUNDLE_HAS_BALANCE"); // burn corresponding nft -> as a result bundle looses its owner _token.burn(bundleId); _unburntBundlesForRiskpoolId[bundle.riskpoolId] -= 1; _changeState(bundleId, BundleState.Burned); } function collateralizePolicy(uint256 bundleId, bytes32 processId, uint256 amount) external override onlyRiskpoolService { IPolicy.Metadata memory metadata = _policy.getMetadata(processId); Bundle storage bundle = _bundles[bundleId]; require(bundle.riskpoolId == _getPoolController().getRiskPoolForProduct(metadata.productId), "ERROR:BUC-019:BUNDLE_NOT_IN_RISKPOOL"); require(bundle.createdAt > 0, "ERROR:BUC-020:BUNDLE_DOES_NOT_EXIST"); require(bundle.state == IBundle.BundleState.Active, "ERROR:BUC-021:BUNDLE_NOT_ACTIVE"); require(bundle.capital >= bundle.lockedCapital + amount, "ERROR:BUC-022:CAPACITY_TOO_LOW"); // might need to be added in a future relase require(_valueLockedPerPolicy[bundleId][processId] == 0, "ERROR:BUC-023:INCREMENTAL_COLLATERALIZATION_NOT_IMPLEMENTED"); bundle.lockedCapital += amount; bundle.updatedAt = block.timestamp; _activePolicies[bundleId] += 1; _valueLockedPerPolicy[bundleId][processId] = amount; uint256 capacityAmount = bundle.capital - bundle.lockedCapital; emit LogBundlePolicyCollateralized(bundleId, processId, amount, capacityAmount); } function processPremium(uint256 bundleId, bytes32 processId, uint256 amount) external override onlyRiskpoolService onlyFundableBundle(bundleId) { IPolicy.Policy memory policy = _policy.getPolicy(processId); require( policy.state != IPolicy.PolicyState.Closed, "ERROR:POL-030:POLICY_STATE_INVALID" ); Bundle storage bundle = _bundles[bundleId]; require(bundle.createdAt > 0, "ERROR:BUC-031:BUNDLE_DOES_NOT_EXIST"); bundle.balance += amount; bundle.updatedAt = block.timestamp; // solhint-disable-line } function processPayout(uint256 bundleId, bytes32 processId, uint256 amount) external override onlyRiskpoolService { IPolicy.Policy memory policy = _policy.getPolicy(processId); require( policy.state != IPolicy.PolicyState.Closed, "ERROR:POL-040:POLICY_STATE_INVALID" ); // check there are policies and there is sufficient locked capital for policy require(_activePolicies[bundleId] > 0, "ERROR:BUC-041:NO_ACTIVE_POLICIES_FOR_BUNDLE"); require(_valueLockedPerPolicy[bundleId][processId] >= amount, "ERROR:BUC-042:COLLATERAL_INSUFFICIENT_FOR_POLICY"); // make sure bundle exists and is not yet closed Bundle storage bundle = _bundles[bundleId]; require(bundle.createdAt > 0, "ERROR:BUC-043:BUNDLE_DOES_NOT_EXIST"); require( bundle.state == IBundle.BundleState.Active || bundle.state == IBundle.BundleState.Locked, "ERROR:BUC-044:BUNDLE_STATE_INVALID"); require(bundle.capital >= amount, "ERROR:BUC-045:CAPITAL_TOO_LOW"); require(bundle.lockedCapital >= amount, "ERROR:BUC-046:LOCKED_CAPITAL_TOO_LOW"); require(bundle.balance >= amount, "ERROR:BUC-047:BALANCE_TOO_LOW"); _valueLockedPerPolicy[bundleId][processId] -= amount; bundle.capital -= amount; bundle.lockedCapital -= amount; bundle.balance -= amount; bundle.updatedAt = block.timestamp; // solhint-disable-line emit LogBundlePayoutProcessed(bundleId, processId, amount); } function releasePolicy(uint256 bundleId, bytes32 processId) external override onlyRiskpoolService returns(uint256 remainingCollateralAmount) { IPolicy.Policy memory policy = _policy.getPolicy(processId); require( policy.state == IPolicy.PolicyState.Closed, "ERROR:POL-050:POLICY_STATE_INVALID" ); // make sure bundle exists and is not yet closed Bundle storage bundle = _bundles[bundleId]; require(bundle.createdAt > 0, "ERROR:BUC-051:BUNDLE_DOES_NOT_EXIST"); require(_activePolicies[bundleId] > 0, "ERROR:BUC-052:NO_ACTIVE_POLICIES_FOR_BUNDLE"); uint256 lockedForPolicyAmount = _valueLockedPerPolicy[bundleId][processId]; // this should never ever fail ... require( bundle.lockedCapital >= lockedForPolicyAmount, "PANIC:BUC-053:UNLOCK_CAPITAL_TOO_BIG" ); // policy no longer relevant for bundle _activePolicies[bundleId] -= 1; delete _valueLockedPerPolicy[bundleId][processId]; // update bundle capital bundle.lockedCapital -= lockedForPolicyAmount; bundle.updatedAt = block.timestamp; // solhint-disable-line uint256 capacityAmount = bundle.capital - bundle.lockedCapital; emit LogBundlePolicyReleased(bundleId, processId, lockedForPolicyAmount, capacityAmount); } function getOwner(uint256 bundleId) public view returns(address) { uint256 tokenId = getBundle(bundleId).tokenId; return _token.ownerOf(tokenId); } function getState(uint256 bundleId) public view returns(BundleState) { return getBundle(bundleId).state; } function getFilter(uint256 bundleId) public view returns(bytes memory) { return getBundle(bundleId).filter; } function getCapacity(uint256 bundleId) public view returns(uint256) { Bundle memory bundle = getBundle(bundleId); return bundle.capital - bundle.lockedCapital; } function getTotalValueLocked(uint256 bundleId) public view returns(uint256) { return getBundle(bundleId).lockedCapital; } function getBalance(uint256 bundleId) public view returns(uint256) { return getBundle(bundleId).balance; } function getToken() external view returns(BundleToken) { return _token; } function getBundle(uint256 bundleId) public view returns(Bundle memory) { Bundle memory bundle = _bundles[bundleId]; require(bundle.createdAt > 0, "ERROR:BUC-060:BUNDLE_DOES_NOT_EXIST"); return bundle; } function bundles() public view returns(uint256) { return _bundleCount; } function unburntBundles(uint256 riskpoolId) external view returns(uint256) { return _unburntBundlesForRiskpoolId[riskpoolId]; } function _getPoolController() internal view returns (PoolController _poolController) { _poolController = PoolController(_getContractAddress("Pool")); } function _changeState(uint256 bundleId, BundleState newState) internal { BundleState oldState = getState(bundleId); _checkStateTransition(oldState, newState); _setState(bundleId, newState); // log entry for successful state change emit LogBundleStateChanged(bundleId, oldState, newState); } function _setState(uint256 bundleId, BundleState newState) internal { _bundles[bundleId].state = newState; _bundles[bundleId].updatedAt = block.timestamp; } function _checkStateTransition(BundleState oldState, BundleState newState) internal pure { if (oldState == BundleState.Active) { require( newState == BundleState.Locked || newState == BundleState.Closed, "ERROR:BUC-070:ACTIVE_INVALID_TRANSITION" ); } else if (oldState == BundleState.Locked) { require( newState == BundleState.Active || newState == BundleState.Closed, "ERROR:BUC-071:LOCKED_INVALID_TRANSITION" ); } else if (oldState == BundleState.Closed) { require( newState == BundleState.Burned, "ERROR:BUC-072:CLOSED_INVALID_TRANSITION" ); } else if (oldState == BundleState.Burned) { revert("ERROR:BUC-073:BURNED_IS_FINAL_STATE"); } else { revert("ERROR:BOC-074:INITIAL_STATE_NOT_HANDLED"); } } }
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.2; import "CoreController.sol"; import "ComponentController.sol"; import "IPolicy.sol"; contract PolicyController is IPolicy, CoreController { // bytes32 public constant NAME = "PolicyController"; // Metadata mapping(bytes32 /* processId */ => Metadata) public metadata; // Applications mapping(bytes32 /* processId */ => Application) public applications; // Policies mapping(bytes32 /* processId */ => Policy) public policies; // Claims mapping(bytes32 /* processId */ => mapping(uint256 /* claimId */ => Claim)) public claims; // Payouts mapping(bytes32 /* processId */ => mapping(uint256 /* payoutId */ => Payout)) public payouts; mapping(bytes32 /* processId */ => uint256) public payoutCount; // counter for assigned processIds, used to ensure unique processIds uint256 private _assigendProcessIds; ComponentController private _component; function _afterInitialize() internal override onlyInitializing { _component = ComponentController(_getContractAddress("Component")); } /* Metadata */ function createPolicyFlow( address owner, uint256 productId, bytes calldata data ) external override onlyPolicyFlow("Policy") returns(bytes32 processId) { require(owner != address(0), "ERROR:POL-001:INVALID_OWNER"); require(_component.isProduct(productId), "ERROR:POL-002:INVALID_PRODUCT"); require(_component.getComponentState(productId) == IComponent.ComponentState.Active, "ERROR:POL-003:PRODUCT_NOT_ACTIVE"); processId = _generateNextProcessId(); Metadata storage meta = metadata[processId]; require(meta.createdAt == 0, "ERROR:POC-004:METADATA_ALREADY_EXISTS"); meta.owner = owner; meta.productId = productId; meta.state = PolicyFlowState.Started; meta.data = data; meta.createdAt = block.timestamp; // solhint-disable-line meta.updatedAt = block.timestamp; // solhint-disable-line emit LogMetadataCreated(owner, processId, productId, PolicyFlowState.Started); } /* Application */ function createApplication( bytes32 processId, uint256 premiumAmount, uint256 sumInsuredAmount, bytes calldata data ) external override onlyPolicyFlow("Policy") { Metadata storage meta = metadata[processId]; require(meta.createdAt > 0, "ERROR:POC-010:METADATA_DOES_NOT_EXIST"); Application storage application = applications[processId]; require(application.createdAt == 0, "ERROR:POC-011:APPLICATION_ALREADY_EXISTS"); require(premiumAmount > 0, "ERROR:POC-012:PREMIUM_AMOUNT_ZERO"); require(sumInsuredAmount > premiumAmount, "ERROR:POC-013:SUM_INSURED_AMOUNT_TOO_SMALL"); application.state = ApplicationState.Applied; application.premiumAmount = premiumAmount; application.sumInsuredAmount = sumInsuredAmount; application.data = data; application.createdAt = block.timestamp; // solhint-disable-line application.updatedAt = block.timestamp; // solhint-disable-line meta.state = PolicyFlowState.Active; meta.updatedAt = block.timestamp; // solhint-disable-line emit LogMetadataStateChanged(processId, meta.state); emit LogApplicationCreated(processId, premiumAmount, sumInsuredAmount); } function collectPremium(bytes32 processId, uint256 amount) external override { Policy storage policy = policies[processId]; require(policy.createdAt > 0, "ERROR:POC-110:POLICY_DOES_NOT_EXIST"); require(policy.premiumPaidAmount + amount <= policy.premiumExpectedAmount, "ERROR:POC-111:AMOUNT_TOO_BIG"); policy.premiumPaidAmount += amount; policy.updatedAt = block.timestamp; // solhint-disable-line emit LogPremiumCollected(processId, amount); } function revokeApplication(bytes32 processId) external override onlyPolicyFlow("Policy") { Metadata storage meta = metadata[processId]; require(meta.createdAt > 0, "ERROR:POC-014:METADATA_DOES_NOT_EXIST"); Application storage application = applications[processId]; require(application.createdAt > 0, "ERROR:POC-015:APPLICATION_DOES_NOT_EXIST"); require(application.state == ApplicationState.Applied, "ERROR:POC-016:APPLICATION_STATE_INVALID"); application.state = ApplicationState.Revoked; application.updatedAt = block.timestamp; // solhint-disable-line meta.state = PolicyFlowState.Finished; meta.updatedAt = block.timestamp; // solhint-disable-line emit LogMetadataStateChanged(processId, meta.state); emit LogApplicationRevoked(processId); } function underwriteApplication(bytes32 processId) external override onlyPolicyFlow("Policy") { Application storage application = applications[processId]; require(application.createdAt > 0, "ERROR:POC-017:APPLICATION_DOES_NOT_EXIST"); require(application.state == ApplicationState.Applied, "ERROR:POC-018:APPLICATION_STATE_INVALID"); application.state = ApplicationState.Underwritten; application.updatedAt = block.timestamp; // solhint-disable-line emit LogApplicationUnderwritten(processId); } function declineApplication(bytes32 processId) external override onlyPolicyFlow("Policy") { Metadata storage meta = metadata[processId]; require(meta.createdAt > 0, "ERROR:POC-019:METADATA_DOES_NOT_EXIST"); Application storage application = applications[processId]; require(application.createdAt > 0, "ERROR:POC-020:APPLICATION_DOES_NOT_EXIST"); require(application.state == ApplicationState.Applied, "ERROR:POC-021:APPLICATION_STATE_INVALID"); application.state = ApplicationState.Declined; application.updatedAt = block.timestamp; // solhint-disable-line meta.state = PolicyFlowState.Finished; meta.updatedAt = block.timestamp; // solhint-disable-line emit LogMetadataStateChanged(processId, meta.state); emit LogApplicationDeclined(processId); } /* Policy */ function createPolicy(bytes32 processId) external override onlyPolicyFlow("Policy") { Application memory application = applications[processId]; require(application.createdAt > 0 && application.state == ApplicationState.Underwritten, "ERROR:POC-022:APPLICATION_ACCESS_INVALID"); Policy storage policy = policies[processId]; require(policy.createdAt == 0, "ERROR:POC-023:POLICY_ALREADY_EXISTS"); policy.state = PolicyState.Active; policy.premiumExpectedAmount = application.premiumAmount; policy.payoutMaxAmount = application.sumInsuredAmount; policy.createdAt = block.timestamp; // solhint-disable-line policy.updatedAt = block.timestamp; // solhint-disable-line emit LogPolicyCreated(processId); } function adjustPremiumSumInsured( bytes32 processId, uint256 expectedPremiumAmount, uint256 sumInsuredAmount ) external override onlyPolicyFlow("Policy") { Application storage application = applications[processId]; require( application.createdAt > 0 && application.state == ApplicationState.Underwritten, "ERROR:POC-024:APPLICATION_ACCESS_INVALID"); require( sumInsuredAmount <= application.sumInsuredAmount, "ERROR:POC-026:APPLICATION_SUM_INSURED_INCREASE_INVALID"); Policy storage policy = policies[processId]; require( policy.createdAt > 0 && policy.state == IPolicy.PolicyState.Active, "ERROR:POC-027:POLICY_ACCESS_INVALID"); require( expectedPremiumAmount > 0 && expectedPremiumAmount >= policy.premiumPaidAmount && expectedPremiumAmount < sumInsuredAmount, "ERROR:POC-025:APPLICATION_PREMIUM_INVALID"); if (sumInsuredAmount != application.sumInsuredAmount) { emit LogApplicationSumInsuredAdjusted(processId, application.sumInsuredAmount, sumInsuredAmount); application.sumInsuredAmount = sumInsuredAmount; application.updatedAt = block.timestamp; // solhint-disable-line policy.payoutMaxAmount = sumInsuredAmount; policy.updatedAt = block.timestamp; // solhint-disable-line } if (expectedPremiumAmount != application.premiumAmount) { emit LogApplicationPremiumAdjusted(processId, application.premiumAmount, expectedPremiumAmount); application.premiumAmount = expectedPremiumAmount; application.updatedAt = block.timestamp; // solhint-disable-line emit LogPolicyPremiumAdjusted(processId, policy.premiumExpectedAmount, expectedPremiumAmount); policy.premiumExpectedAmount = expectedPremiumAmount; policy.updatedAt = block.timestamp; // solhint-disable-line } } function expirePolicy(bytes32 processId) external override onlyPolicyFlow("Policy") { Policy storage policy = policies[processId]; require(policy.createdAt > 0, "ERROR:POC-028:POLICY_DOES_NOT_EXIST"); require(policy.state == PolicyState.Active, "ERROR:POC-029:APPLICATION_STATE_INVALID"); policy.state = PolicyState.Expired; policy.updatedAt = block.timestamp; // solhint-disable-line emit LogPolicyExpired(processId); } function closePolicy(bytes32 processId) external override onlyPolicyFlow("Policy") { Metadata storage meta = metadata[processId]; require(meta.createdAt > 0, "ERROR:POC-030:METADATA_DOES_NOT_EXIST"); Policy storage policy = policies[processId]; require(policy.createdAt > 0, "ERROR:POC-031:POLICY_DOES_NOT_EXIST"); require(policy.state == PolicyState.Expired, "ERROR:POC-032:POLICY_STATE_INVALID"); require(policy.openClaimsCount == 0, "ERROR:POC-033:POLICY_HAS_OPEN_CLAIMS"); policy.state = PolicyState.Closed; policy.updatedAt = block.timestamp; // solhint-disable-line meta.state = PolicyFlowState.Finished; meta.updatedAt = block.timestamp; // solhint-disable-line emit LogMetadataStateChanged(processId, meta.state); emit LogPolicyClosed(processId); } /* Claim */ function createClaim( bytes32 processId, uint256 claimAmount, bytes calldata data ) external override onlyPolicyFlow("Policy") returns (uint256 claimId) { Policy storage policy = policies[processId]; require(policy.createdAt > 0, "ERROR:POC-040:POLICY_DOES_NOT_EXIST"); require(policy.state == IPolicy.PolicyState.Active, "ERROR:POC-041:POLICY_NOT_ACTIVE"); // no validation of claimAmount > 0 here to explicitly allow claims with amount 0. This can be useful for parametric insurance // to have proof that the claim calculation was executed without entitlement to payment. require(policy.payoutAmount + claimAmount <= policy.payoutMaxAmount, "ERROR:POC-042:CLAIM_AMOUNT_EXCEEDS_MAX_PAYOUT"); claimId = policy.claimsCount; Claim storage claim = claims[processId][claimId]; require(claim.createdAt == 0, "ERROR:POC-043:CLAIM_ALREADY_EXISTS"); claim.state = ClaimState.Applied; claim.claimAmount = claimAmount; claim.data = data; claim.createdAt = block.timestamp; // solhint-disable-line claim.updatedAt = block.timestamp; // solhint-disable-line policy.claimsCount++; policy.openClaimsCount++; policy.updatedAt = block.timestamp; // solhint-disable-line emit LogClaimCreated(processId, claimId, claimAmount); } function confirmClaim( bytes32 processId, uint256 claimId, uint256 confirmedAmount ) external override onlyPolicyFlow("Policy") { Policy storage policy = policies[processId]; require(policy.createdAt > 0, "ERROR:POC-050:POLICY_DOES_NOT_EXIST"); require(policy.openClaimsCount > 0, "ERROR:POC-051:POLICY_WITHOUT_OPEN_CLAIMS"); // no validation of claimAmount > 0 here as is it possible to have claims with amount 0 (see createClaim()). require(policy.payoutAmount + confirmedAmount <= policy.payoutMaxAmount, "ERROR:POC-052:PAYOUT_MAX_AMOUNT_EXCEEDED"); Claim storage claim = claims[processId][claimId]; require(claim.createdAt > 0, "ERROR:POC-053:CLAIM_DOES_NOT_EXIST"); require(claim.state == ClaimState.Applied, "ERROR:POC-054:CLAIM_STATE_INVALID"); claim.state = ClaimState.Confirmed; claim.claimAmount = confirmedAmount; claim.updatedAt = block.timestamp; // solhint-disable-line policy.payoutAmount += confirmedAmount; policy.updatedAt = block.timestamp; // solhint-disable-line emit LogClaimConfirmed(processId, claimId, confirmedAmount); } function declineClaim(bytes32 processId, uint256 claimId) external override onlyPolicyFlow("Policy") { Policy storage policy = policies[processId]; require(policy.createdAt > 0, "ERROR:POC-060:POLICY_DOES_NOT_EXIST"); require(policy.openClaimsCount > 0, "ERROR:POC-061:POLICY_WITHOUT_OPEN_CLAIMS"); Claim storage claim = claims[processId][claimId]; require(claim.createdAt > 0, "ERROR:POC-062:CLAIM_DOES_NOT_EXIST"); require(claim.state == ClaimState.Applied, "ERROR:POC-063:CLAIM_STATE_INVALID"); claim.state = ClaimState.Declined; claim.updatedAt = block.timestamp; // solhint-disable-line policy.updatedAt = block.timestamp; // solhint-disable-line emit LogClaimDeclined(processId, claimId); } function closeClaim(bytes32 processId, uint256 claimId) external override onlyPolicyFlow("Policy") { Policy storage policy = policies[processId]; require(policy.createdAt > 0, "ERROR:POC-070:POLICY_DOES_NOT_EXIST"); require(policy.openClaimsCount > 0, "ERROR:POC-071:POLICY_WITHOUT_OPEN_CLAIMS"); Claim storage claim = claims[processId][claimId]; require(claim.createdAt > 0, "ERROR:POC-072:CLAIM_DOES_NOT_EXIST"); require( claim.state == ClaimState.Confirmed || claim.state == ClaimState.Declined, "ERROR:POC-073:CLAIM_STATE_INVALID"); require( (claim.state == ClaimState.Confirmed && claim.claimAmount == claim.paidAmount) || (claim.state == ClaimState.Declined), "ERROR:POC-074:CLAIM_WITH_UNPAID_PAYOUTS" ); claim.state = ClaimState.Closed; claim.updatedAt = block.timestamp; // solhint-disable-line policy.openClaimsCount--; policy.updatedAt = block.timestamp; // solhint-disable-line emit LogClaimClosed(processId, claimId); } /* Payout */ function createPayout( bytes32 processId, uint256 claimId, uint256 payoutAmount, bytes calldata data ) external override onlyPolicyFlow("Policy") returns (uint256 payoutId) { Policy storage policy = policies[processId]; require(policy.createdAt > 0, "ERROR:POC-080:POLICY_DOES_NOT_EXIST"); Claim storage claim = claims[processId][claimId]; require(claim.createdAt > 0, "ERROR:POC-081:CLAIM_DOES_NOT_EXIST"); require(claim.state == IPolicy.ClaimState.Confirmed, "ERROR:POC-082:CLAIM_NOT_CONFIRMED"); require(payoutAmount > 0, "ERROR:POC-083:PAYOUT_AMOUNT_ZERO_INVALID"); require( claim.paidAmount + payoutAmount <= claim.claimAmount, "ERROR:POC-084:PAYOUT_AMOUNT_TOO_BIG" ); payoutId = payoutCount[processId]; Payout storage payout = payouts[processId][payoutId]; require(payout.createdAt == 0, "ERROR:POC-085:PAYOUT_ALREADY_EXISTS"); payout.claimId = claimId; payout.amount = payoutAmount; payout.data = data; payout.state = PayoutState.Expected; payout.createdAt = block.timestamp; // solhint-disable-line payout.updatedAt = block.timestamp; // solhint-disable-line payoutCount[processId]++; policy.updatedAt = block.timestamp; // solhint-disable-line emit LogPayoutCreated(processId, claimId, payoutId, payoutAmount); } function processPayout( bytes32 processId, uint256 payoutId ) external override onlyPolicyFlow("Policy") { Policy storage policy = policies[processId]; require(policy.createdAt > 0, "ERROR:POC-090:POLICY_DOES_NOT_EXIST"); require(policy.openClaimsCount > 0, "ERROR:POC-091:POLICY_WITHOUT_OPEN_CLAIMS"); Payout storage payout = payouts[processId][payoutId]; require(payout.createdAt > 0, "ERROR:POC-092:PAYOUT_DOES_NOT_EXIST"); require(payout.state == PayoutState.Expected, "ERROR:POC-093:PAYOUT_ALREADY_PAIDOUT"); payout.state = IPolicy.PayoutState.PaidOut; payout.updatedAt = block.timestamp; // solhint-disable-line emit LogPayoutProcessed(processId, payoutId); Claim storage claim = claims[processId][payout.claimId]; claim.paidAmount += payout.amount; claim.updatedAt = block.timestamp; // solhint-disable-line // check if claim can be closed if (claim.claimAmount == claim.paidAmount) { claim.state = IPolicy.ClaimState.Closed; policy.openClaimsCount -= 1; policy.updatedAt = block.timestamp; // solhint-disable-line emit LogClaimClosed(processId, payout.claimId); } } function getMetadata(bytes32 processId) public view returns (IPolicy.Metadata memory _metadata) { _metadata = metadata[processId]; require(_metadata.createdAt > 0, "ERROR:POC-100:METADATA_DOES_NOT_EXIST"); } function getApplication(bytes32 processId) public view returns (IPolicy.Application memory application) { application = applications[processId]; require(application.createdAt > 0, "ERROR:POC-101:APPLICATION_DOES_NOT_EXIST"); } function getNumberOfClaims(bytes32 processId) external view returns(uint256 numberOfClaims) { numberOfClaims = getPolicy(processId).claimsCount; } function getNumberOfPayouts(bytes32 processId) external view returns(uint256 numberOfPayouts) { numberOfPayouts = payoutCount[processId]; } function getPolicy(bytes32 processId) public view returns (IPolicy.Policy memory policy) { policy = policies[processId]; require(policy.createdAt > 0, "ERROR:POC-102:POLICY_DOES_NOT_EXIST"); } function getClaim(bytes32 processId, uint256 claimId) public view returns (IPolicy.Claim memory claim) { claim = claims[processId][claimId]; require(claim.createdAt > 0, "ERROR:POC-103:CLAIM_DOES_NOT_EXIST"); } function getPayout(bytes32 processId, uint256 payoutId) public view returns (IPolicy.Payout memory payout) { payout = payouts[processId][payoutId]; require(payout.createdAt > 0, "ERROR:POC-104:PAYOUT_DOES_NOT_EXIST"); } function processIds() external view returns (uint256) { return _assigendProcessIds; } function _generateNextProcessId() private returns(bytes32 processId) { _assigendProcessIds++; processId = keccak256( abi.encodePacked( block.chainid, address(_registry), _assigendProcessIds ) ); } }
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.2; import "Ownable.sol"; import "ERC721.sol"; import "IBundleToken.sol"; contract BundleToken is IBundleToken, ERC721, Ownable { string public constant NAME = "GIF Bundle Token"; string public constant SYMBOL = "BTK"; mapping(uint256 /** tokenId */ => uint256 /** bundleId */) public bundleIdForTokenId; address private _bundleModule; uint256 private _totalSupply; modifier onlyBundleModule() { require(_bundleModule != address(0), "ERROR:BTK-001:NOT_INITIALIZED"); require(_msgSender() == _bundleModule, "ERROR:BTK-002:NOT_BUNDLE_MODULE"); _; } constructor() ERC721(NAME, SYMBOL) Ownable() { } function setBundleModule(address bundleModule) external { require(_bundleModule == address(0), "ERROR:BTK-003:BUNDLE_MODULE_ALREADY_DEFINED"); require(bundleModule != address(0), "ERROR:BTK-004:INVALID_BUNDLE_MODULE_ADDRESS"); _bundleModule = bundleModule; } function mint(uint256 bundleId, address to) external onlyBundleModule returns(uint256 tokenId) { _totalSupply++; tokenId = _totalSupply; bundleIdForTokenId[tokenId] = bundleId; _safeMint(to, tokenId); emit LogBundleTokenMinted(bundleId, tokenId, to); } function burn(uint256 tokenId) external onlyBundleModule { require(_exists(tokenId), "ERROR:BTK-005:TOKEN_ID_INVALID"); _burn(tokenId); emit LogBundleTokenBurned(bundleIdForTokenId[tokenId], tokenId); } function burned(uint tokenId) external override view returns(bool isBurned) { isBurned = tokenId <= _totalSupply && !_exists(tokenId); } function getBundleId(uint256 tokenId) external override view returns(uint256) { return bundleIdForTokenId[tokenId]; } function getBundleModuleAddress() external view returns(address) { return _bundleModule; } function exists(uint256 tokenId) external override view returns(bool) { return tokenId <= _totalSupply; } function totalSupply() external override view returns(uint256 tokenCount) { return _totalSupply; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol) pragma solidity ^0.8.0; import "IERC721.sol"; import "IERC721Receiver.sol"; import "IERC721Metadata.sol"; import "Address.sol"; import "Context.sol"; import "Strings.sol"; import "ERC165.sol"; /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata extension, but not including the Enumerable extension, which is available separately as * {ERC721Enumerable}. */ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata { using Address for address; using Strings for uint256; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to owner address mapping(uint256 => address) private _owners; // Mapping owner address to token count mapping(address => uint256) private _balances; // Mapping from token ID to approved address mapping(uint256 => address) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual override returns (uint256) { require(owner != address(0), "ERC721: address zero is not a valid owner"); return _balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { address owner = _owners[tokenId]; require(owner != address(0), "ERC721: invalid token ID"); return owner; } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { _requireMinted(tokenId); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual override { address owner = ERC721.ownerOf(tokenId); require(to != owner, "ERC721: approval to current owner"); require( _msgSender() == owner || isApprovedForAll(owner, _msgSender()), "ERC721: approve caller is not token owner nor approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { _requireMinted(tokenId); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { _setApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom( address from, address to, uint256 tokenId ) public virtual override { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner nor approved"); _transfer(from, to, tokenId); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public virtual override { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory data ) public virtual override { require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner nor approved"); _safeTransfer(from, to, tokenId, data); } /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * `data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer( address from, address to, uint256 tokenId, bytes memory data ) internal virtual { _transfer(from, to, tokenId); require(_checkOnERC721Received(from, to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted (`_mint`), * and stop existing when they are burned (`_burn`). */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _owners[tokenId] != address(0); } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { address owner = ERC721.ownerOf(tokenId); return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender); } /** * @dev Safely mints `tokenId` and transfers it to `to`. * * Requirements: * * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal virtual { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint( address to, uint256 tokenId, bytes memory data ) internal virtual { _mint(to, tokenId); require( _checkOnERC721Received(address(0), to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer" ); } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal virtual { require(to != address(0), "ERC721: mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _beforeTokenTransfer(address(0), to, tokenId); _balances[to] += 1; _owners[tokenId] = to; emit Transfer(address(0), to, tokenId); _afterTokenTransfer(address(0), to, tokenId); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721.ownerOf(tokenId); _beforeTokenTransfer(owner, address(0), tokenId); // Clear approvals _approve(address(0), tokenId); _balances[owner] -= 1; delete _owners[tokenId]; emit Transfer(owner, address(0), tokenId); _afterTokenTransfer(owner, address(0), tokenId); } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer( address from, address to, uint256 tokenId ) internal virtual { require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); require(to != address(0), "ERC721: transfer to the zero address"); _beforeTokenTransfer(from, to, tokenId); // Clear approvals from the previous owner _approve(address(0), tokenId); _balances[from] -= 1; _balances[to] += 1; _owners[tokenId] = to; emit Transfer(from, to, tokenId); _afterTokenTransfer(from, to, tokenId); } /** * @dev Approve `to` to operate on `tokenId` * * Emits an {Approval} event. */ function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ERC721.ownerOf(tokenId), to, tokenId); } /** * @dev Approve `operator` to operate on all of `owner` tokens * * Emits an {ApprovalForAll} event. */ function _setApprovalForAll( address owner, address operator, bool approved ) internal virtual { require(owner != operator, "ERC721: approve to caller"); _operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Reverts if the `tokenId` has not been minted yet. */ function _requireMinted(uint256 tokenId) internal view virtual { require(_exists(tokenId), "ERC721: invalid token ID"); } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. * The call is not executed if the target address is not a contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param data bytes optional data to send along with the call * @return bool whether the call correctly returned the expected magic value */ function _checkOnERC721Received( address from, address to, uint256 tokenId, bytes memory data ) private returns (bool) { if (to.isContract()) { try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) { return retval == IERC721Receiver.onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert("ERC721: transfer to non ERC721Receiver implementer"); } else { /// @solidity memory-safe-assembly assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } /** * @dev Hook that is called before any token transfer. This includes minting * and burning. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, ``from``'s `tokenId` will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 tokenId ) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 tokenId ) internal virtual {} }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol) pragma solidity ^0.8.0; import "IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.2; import "IERC721.sol"; interface IBundleToken is IERC721 { event LogBundleTokenMinted(uint256 bundleId, uint256 tokenId, address tokenOwner); event LogBundleTokenBurned(uint256 bundleId, uint256 tokenId); function burned(uint tokenId) external view returns(bool isBurned); function exists(uint256 tokenId) external view returns(bool doesExist); function getBundleId(uint256 tokenId) external view returns(uint256 bundleId); function totalSupply() external view returns(uint256 tokenCount); }
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.2; import "ComponentController.sol"; import "PolicyController.sol"; import "BundleController.sol"; import "CoreController.sol"; import "IPool.sol"; import "IComponent.sol"; import "IRiskpool.sol"; import "EnumerableSet.sol"; contract PoolController is IPool, CoreController { using EnumerableSet for EnumerableSet.UintSet; // used for representation of collateralization // collateralization between 0 and 1 (1=100%) // value might be larger when overcollateralization uint256 public constant FULL_COLLATERALIZATION_LEVEL = 10**18; // upper limit for overcollateralization at 200% uint256 public constant COLLATERALIZATION_LEVEL_CAP = 2 * FULL_COLLATERALIZATION_LEVEL; uint256 public constant DEFAULT_MAX_NUMBER_OF_ACTIVE_BUNDLES = 1; mapping(bytes32 /* processId */ => uint256 /* collateralAmount*/ ) private _collateralAmount; mapping(uint256 /* productId */ => uint256 /* riskpoolId */) private _riskpoolIdForProductId; mapping(uint256 /* riskpoolId */ => IPool.Pool) private _riskpools; mapping(uint256 /* riskpoolId */ => uint256 /* maxmimumNumberOfActiveBundles */) private _maxmimumNumberOfActiveBundlesForRiskpoolId; mapping(uint256 /* riskpoolId */ => EnumerableSet.UintSet /* active bundle id set */) private _activeBundleIdsForRiskpoolId; uint256 [] private _riskpoolIds; ComponentController private _component; PolicyController private _policy; BundleController private _bundle; modifier onlyInstanceOperatorService() { require( _msgSender() == _getContractAddress("InstanceOperatorService"), "ERROR:POL-001:NOT_INSTANCE_OPERATOR" ); _; } modifier onlyRiskpoolService() { require( _msgSender() == _getContractAddress("RiskpoolService"), "ERROR:POL-002:NOT_RISKPOOL_SERVICE" ); _; } modifier onlyTreasury() { require( _msgSender() == _getContractAddress("Treasury"), "ERROR:POL-003:NOT_TREASURY" ); _; } function _afterInitialize() internal override onlyInitializing { _component = ComponentController(_getContractAddress("Component")); _policy = PolicyController(_getContractAddress("Policy")); _bundle = BundleController(_getContractAddress("Bundle")); } function registerRiskpool( uint256 riskpoolId, address wallet, address erc20Token, uint256 collateralizationLevel, uint256 sumOfSumInsuredCap ) external override onlyRiskpoolService { IPool.Pool storage pool = _riskpools[riskpoolId]; _riskpoolIds.push(riskpoolId); _maxmimumNumberOfActiveBundlesForRiskpoolId[riskpoolId] = DEFAULT_MAX_NUMBER_OF_ACTIVE_BUNDLES; require(pool.createdAt == 0, "ERROR:POL-004:RISKPOOL_ALREADY_REGISTERED"); require(wallet != address(0), "ERROR:POL-005:WALLET_ADDRESS_ZERO"); require(erc20Token != address(0), "ERROR:POL-006:ERC20_ADDRESS_ZERO"); require(collateralizationLevel <= COLLATERALIZATION_LEVEL_CAP, "ERROR:POL-007:COLLATERALIZATION_lEVEl_TOO_HIGH"); require(sumOfSumInsuredCap > 0, "ERROR:POL-008:SUM_OF_SUM_INSURED_CAP_ZERO"); pool.id = riskpoolId; pool.wallet = wallet; pool.erc20Token = erc20Token; pool.collateralizationLevel = collateralizationLevel; pool.sumOfSumInsuredCap = sumOfSumInsuredCap; pool.sumOfSumInsuredAtRisk = 0; pool.capital = 0; pool.lockedCapital = 0; pool.balance = 0; pool.createdAt = block.timestamp; pool.updatedAt = block.timestamp; emit LogRiskpoolRegistered(riskpoolId, wallet, erc20Token, collateralizationLevel, sumOfSumInsuredCap); } function setRiskpoolForProduct(uint256 productId, uint256 riskpoolId) external override onlyInstanceOperatorService { require(_component.isProduct(productId), "ERROR:POL-010:NOT_PRODUCT"); require(_component.isRiskpool(riskpoolId), "ERROR:POL-011:NOT_RISKPOOL"); require(_riskpoolIdForProductId[productId] == 0, "ERROR:POL-012:RISKPOOL_ALREADY_SET"); _riskpoolIdForProductId[productId] = riskpoolId; } function fund(uint256 riskpoolId, uint256 amount) external onlyRiskpoolService { IPool.Pool storage pool = _riskpools[riskpoolId]; pool.capital += amount; pool.balance += amount; pool.updatedAt = block.timestamp; } function defund(uint256 riskpoolId, uint256 amount) external onlyRiskpoolService { IPool.Pool storage pool = _riskpools[riskpoolId]; if (pool.capital >= amount) { pool.capital -= amount; } else { pool.capital = 0; } pool.balance -= amount; pool.updatedAt = block.timestamp; } function underwrite(bytes32 processId) external override onlyPolicyFlow("Pool") returns(bool success) { // check that application is in applied state IPolicy.Application memory application = _policy.getApplication(processId); require( application.state == IPolicy.ApplicationState.Applied, "ERROR:POL-020:APPLICATION_STATE_INVALID" ); // determine riskpool responsible for application IPolicy.Metadata memory metadata = _policy.getMetadata(processId); uint256 riskpoolId = _riskpoolIdForProductId[metadata.productId]; require( _component.getComponentState(riskpoolId) == IComponent.ComponentState.Active, "ERROR:POL-021:RISKPOOL_NOT_ACTIVE" ); // calculate required collateral amount uint256 sumInsuredAmount = application.sumInsuredAmount; uint256 collateralAmount = calculateCollateral(riskpoolId, sumInsuredAmount); _collateralAmount[processId] = collateralAmount; emit LogRiskpoolRequiredCollateral(processId, sumInsuredAmount, collateralAmount); // check that riskpool stays inside sum insured cap when underwriting this application IPool.Pool storage pool = _riskpools[riskpoolId]; require( pool.sumOfSumInsuredCap >= pool.sumOfSumInsuredAtRisk + sumInsuredAmount, "ERROR:POL-022:RISKPOOL_SUM_INSURED_CAP_EXCEEDED" ); // ask riskpool to secure application IRiskpool riskpool = _getRiskpoolComponent(metadata); success = riskpool.collateralizePolicy(processId, collateralAmount); if (success) { pool.sumOfSumInsuredAtRisk += sumInsuredAmount; pool.lockedCapital += collateralAmount; pool.updatedAt = block.timestamp; emit LogRiskpoolCollateralizationSucceeded(riskpoolId, processId, sumInsuredAmount); } else { emit LogRiskpoolCollateralizationFailed(riskpoolId, processId, sumInsuredAmount); } } function calculateCollateral(uint256 riskpoolId, uint256 sumInsuredAmount) public view returns (uint256 collateralAmount) { uint256 collateralization = getRiskpool(riskpoolId).collateralizationLevel; // fully collateralized case if (collateralization == FULL_COLLATERALIZATION_LEVEL) { collateralAmount = sumInsuredAmount; // over or under collateralized case } else if (collateralization > 0) { collateralAmount = (collateralization * sumInsuredAmount) / FULL_COLLATERALIZATION_LEVEL; } // collateralization == 0, eg complete risk coverd by re insurance outside gif else { collateralAmount = 0; } } function processPremium(bytes32 processId, uint256 amount) external override onlyPolicyFlow("Pool") { IPolicy.Metadata memory metadata = _policy.getMetadata(processId); IRiskpool riskpool = _getRiskpoolComponent(metadata); riskpool.processPolicyPremium(processId, amount); uint256 riskpoolId = _riskpoolIdForProductId[metadata.productId]; IPool.Pool storage pool = _riskpools[riskpoolId]; pool.balance += amount; pool.updatedAt = block.timestamp; } function processPayout(bytes32 processId, uint256 amount) external override onlyPolicyFlow("Pool") { IPolicy.Metadata memory metadata = _policy.getMetadata(processId); uint256 riskpoolId = _riskpoolIdForProductId[metadata.productId]; IPool.Pool storage pool = _riskpools[riskpoolId]; require(pool.createdAt > 0, "ERROR:POL-026:RISKPOOL_ID_INVALID"); require(pool.capital >= amount, "ERROR:POL-027:CAPITAL_TOO_LOW"); require(pool.lockedCapital >= amount, "ERROR:POL-028:LOCKED_CAPITAL_TOO_LOW"); require(pool.balance >= amount, "ERROR:POL-029:BALANCE_TOO_LOW"); pool.capital -= amount; pool.lockedCapital -= amount; pool.balance -= amount; pool.updatedAt = block.timestamp; // solhint-disable-line IRiskpool riskpool = _getRiskpoolComponent(metadata); riskpool.processPolicyPayout(processId, amount); } function release(bytes32 processId) external override onlyPolicyFlow("Pool") { IPolicy.Policy memory policy = _policy.getPolicy(processId); require( policy.state == IPolicy.PolicyState.Closed, "ERROR:POL-025:POLICY_STATE_INVALID" ); IPolicy.Metadata memory metadata = _policy.getMetadata(processId); IRiskpool riskpool = _getRiskpoolComponent(metadata); riskpool.releasePolicy(processId); IPolicy.Application memory application = _policy.getApplication(processId); uint256 riskpoolId = _riskpoolIdForProductId[metadata.productId]; IPool.Pool storage pool = _riskpools[riskpoolId]; uint256 remainingCollateralAmount = _collateralAmount[processId] - policy.payoutAmount; pool.sumOfSumInsuredAtRisk -= application.sumInsuredAmount; pool.lockedCapital -= remainingCollateralAmount; pool.updatedAt = block.timestamp; // solhint-disable-line // free memory delete _collateralAmount[processId]; emit LogRiskpoolCollateralReleased(riskpoolId, processId, remainingCollateralAmount); } function setMaximumNumberOfActiveBundles(uint256 riskpoolId, uint256 maxNumberOfActiveBundles) external onlyRiskpoolService { require(maxNumberOfActiveBundles > 0, "ERROR:POL-032:MAX_NUMBER_OF_ACTIVE_BUNDLES_INVALID"); _maxmimumNumberOfActiveBundlesForRiskpoolId[riskpoolId] = maxNumberOfActiveBundles; } function getMaximumNumberOfActiveBundles(uint256 riskpoolId) public view returns(uint256 maximumNumberOfActiveBundles) { return _maxmimumNumberOfActiveBundlesForRiskpoolId[riskpoolId]; } function riskpools() external view returns(uint256 idx) { return _riskpoolIds.length; } function getRiskpool(uint256 riskpoolId) public view returns(IPool.Pool memory riskPool) { riskPool = _riskpools[riskpoolId]; require(riskPool.createdAt > 0, "ERROR:POL-040:RISKPOOL_NOT_REGISTERED"); } function getRiskPoolForProduct(uint256 productId) external view returns (uint256 riskpoolId) { return _riskpoolIdForProductId[productId]; } function activeBundles(uint256 riskpoolId) external view returns(uint256 numberOfActiveBundles) { return EnumerableSet.length(_activeBundleIdsForRiskpoolId[riskpoolId]); } function getActiveBundleId(uint256 riskpoolId, uint256 bundleIdx) external view returns(uint256 bundleId) { require( bundleIdx < EnumerableSet.length(_activeBundleIdsForRiskpoolId[riskpoolId]), "ERROR:POL-041:BUNDLE_IDX_TOO_LARGE" ); return EnumerableSet.at(_activeBundleIdsForRiskpoolId[riskpoolId], bundleIdx); } function addBundleIdToActiveSet(uint256 riskpoolId, uint256 bundleId) external onlyRiskpoolService { require( !EnumerableSet.contains(_activeBundleIdsForRiskpoolId[riskpoolId], bundleId), "ERROR:POL-042:BUNDLE_ID_ALREADY_IN_SET" ); require( EnumerableSet.length(_activeBundleIdsForRiskpoolId[riskpoolId]) < _maxmimumNumberOfActiveBundlesForRiskpoolId[riskpoolId], "ERROR:POL-043:MAXIMUM_NUMBER_OF_ACTIVE_BUNDLES_REACHED" ); EnumerableSet.add(_activeBundleIdsForRiskpoolId[riskpoolId], bundleId); } function removeBundleIdFromActiveSet(uint256 riskpoolId, uint256 bundleId) external onlyRiskpoolService { require( EnumerableSet.contains(_activeBundleIdsForRiskpoolId[riskpoolId], bundleId), "ERROR:POL-044:BUNDLE_ID_NOT_IN_SET" ); EnumerableSet.remove(_activeBundleIdsForRiskpoolId[riskpoolId], bundleId); } function getFullCollateralizationLevel() external pure returns (uint256) { return FULL_COLLATERALIZATION_LEVEL; } function _getRiskpoolComponent(IPolicy.Metadata memory metadata) internal view returns (IRiskpool riskpool) { uint256 riskpoolId = _riskpoolIdForProductId[metadata.productId]; require(riskpoolId > 0, "ERROR:POL-045:RISKPOOL_DOES_NOT_EXIST"); riskpool = _getRiskpoolForId(riskpoolId); } function _getRiskpoolForId(uint256 riskpoolId) internal view returns (IRiskpool riskpool) { require(_component.isRiskpool(riskpoolId), "ERROR:POL-046:COMPONENT_NOT_RISKPOOL"); IComponent cmp = _component.getComponent(riskpoolId); riskpool = IRiskpool(address(cmp)); } }
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.2; interface IPool { event LogRiskpoolRegistered( uint256 riskpoolId, address wallet, address erc20Token, uint256 collateralizationLevel, uint256 sumOfSumInsuredCap ); event LogRiskpoolRequiredCollateral(bytes32 processId, uint256 sumInsured, uint256 collateral); event LogRiskpoolCollateralizationFailed(uint256 riskpoolId, bytes32 processId, uint256 amount); event LogRiskpoolCollateralizationSucceeded(uint256 riskpoolId, bytes32 processId, uint256 amount); event LogRiskpoolCollateralReleased(uint256 riskpoolId, bytes32 processId, uint256 amount); struct Pool { uint256 id; // matches component id of riskpool address wallet; // riskpool wallet address erc20Token; // the value token of the riskpool uint256 collateralizationLevel; // required collateralization level to cover new policies uint256 sumOfSumInsuredCap; // max sum of sum insured the pool is allowed to secure uint256 sumOfSumInsuredAtRisk; // current sum of sum insured at risk in this pool uint256 capital; // net investment capital amount (<= balance) uint256 lockedCapital; // capital amount linked to collateralizaion of non-closed policies (<= capital) uint256 balance; // total amount of funds: net investment capital + net premiums - payouts uint256 createdAt; uint256 updatedAt; } function registerRiskpool( uint256 riskpoolId, address wallet, address erc20Token, uint256 collateralizationLevel, uint256 sumOfSumInsuredCap ) external; function setRiskpoolForProduct(uint256 productId, uint256 riskpoolId) external; function underwrite(bytes32 processId) external returns(bool success); function processPremium(bytes32 processId, uint256 amount) external; function processPayout(bytes32 processId, uint256 amount) external; function release(bytes32 processId) external; }
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.2; import "ComponentController.sol"; import "PolicyController.sol"; import "BundleController.sol"; import "PoolController.sol"; import "CoreController.sol"; import "TransferHelper.sol"; import "IComponent.sol"; import "IProduct.sol"; import "IPolicy.sol"; import "ITreasury.sol"; import "Pausable.sol"; import "IERC20.sol"; import "Strings.sol"; contract TreasuryModule is ITreasury, CoreController, Pausable { uint256 public constant FRACTION_FULL_UNIT = 10**18; uint256 public constant FRACTIONAL_FEE_MAX = FRACTION_FULL_UNIT / 4; // max frctional fee is 25% event LogTransferHelperInputValidation1Failed(bool tokenIsContract, address from, address to); event LogTransferHelperInputValidation2Failed(uint256 balance, uint256 allowance); event LogTransferHelperCallFailed(bool callSuccess, uint256 returnDataLength, bytes returnData); address private _instanceWalletAddress; mapping(uint256 => address) private _riskpoolWallet; // riskpoolId => walletAddress mapping(uint256 => FeeSpecification) private _fees; // componentId => fee specification mapping(uint256 => IERC20) private _componentToken; // productId/riskpoolId => erc20Address BundleController private _bundle; ComponentController private _component; PolicyController private _policy; PoolController private _pool; modifier instanceWalletDefined() { require( _instanceWalletAddress != address(0), "ERROR:TRS-001:INSTANCE_WALLET_UNDEFINED"); _; } modifier riskpoolWalletDefinedForProcess(bytes32 processId) { (uint256 riskpoolId, address walletAddress) = _getRiskpoolWallet(processId); require( walletAddress != address(0), "ERROR:TRS-002:RISKPOOL_WALLET_UNDEFINED"); _; } modifier riskpoolWalletDefinedForBundle(uint256 bundleId) { IBundle.Bundle memory bundle = _bundle.getBundle(bundleId); require( getRiskpoolWallet(bundle.riskpoolId) != address(0), "ERROR:TRS-003:RISKPOOL_WALLET_UNDEFINED"); _; } // surrogate modifier for whenNotPaused to create treasury specific error message modifier whenNotSuspended() { require(!paused(), "ERROR:TRS-004:TREASURY_SUSPENDED"); _; } modifier onlyRiskpoolService() { require( _msgSender() == _getContractAddress("RiskpoolService"), "ERROR:TRS-005:NOT_RISKPOOL_SERVICE" ); _; } function _afterInitialize() internal override onlyInitializing { _bundle = BundleController(_getContractAddress("Bundle")); _component = ComponentController(_getContractAddress("Component")); _policy = PolicyController(_getContractAddress("Policy")); _pool = PoolController(_getContractAddress("Pool")); } function suspend() external onlyInstanceOperator { _pause(); emit LogTreasurySuspended(); } function resume() external onlyInstanceOperator { _unpause(); emit LogTreasuryResumed(); } function setProductToken(uint256 productId, address erc20Address) external override whenNotSuspended onlyInstanceOperator { require(erc20Address != address(0), "ERROR:TRS-010:TOKEN_ADDRESS_ZERO"); IComponent component = _component.getComponent(productId); require(_component.isProduct(productId), "ERROR:TRS-011:NOT_PRODUCT"); require(address(_componentToken[productId]) == address(0), "ERROR:TRS-012:PRODUCT_TOKEN_ALREADY_SET"); uint256 riskpoolId = _pool.getRiskPoolForProduct(productId); // require if riskpool token is already set and product token does match riskpool token require(address(_componentToken[riskpoolId]) == address(0) || address(_componentToken[riskpoolId]) == address(IProduct(address(component)).getToken()), "ERROR:TRS-014:TOKEN_ADDRESS_NOT_MACHING"); _componentToken[productId] = IERC20(erc20Address); _componentToken[riskpoolId] = IERC20(erc20Address); emit LogTreasuryProductTokenSet(productId, riskpoolId, erc20Address); } function setInstanceWallet(address instanceWalletAddress) external override whenNotSuspended onlyInstanceOperator { require(instanceWalletAddress != address(0), "ERROR:TRS-015:WALLET_ADDRESS_ZERO"); _instanceWalletAddress = instanceWalletAddress; emit LogTreasuryInstanceWalletSet (instanceWalletAddress); } function setRiskpoolWallet(uint256 riskpoolId, address riskpoolWalletAddress) external override whenNotSuspended onlyInstanceOperator { IComponent component = _component.getComponent(riskpoolId); require(_component.isRiskpool(riskpoolId), "ERROR:TRS-016:NOT_RISKPOOL"); require(riskpoolWalletAddress != address(0), "ERROR:TRS-017:WALLET_ADDRESS_ZERO"); _riskpoolWallet[riskpoolId] = riskpoolWalletAddress; emit LogTreasuryRiskpoolWalletSet (riskpoolId, riskpoolWalletAddress); } function createFeeSpecification( uint256 componentId, uint256 fixedFee, uint256 fractionalFee, bytes calldata feeCalculationData ) external override view returns(FeeSpecification memory) { require(_component.isProduct(componentId) || _component.isRiskpool(componentId), "ERROR:TRS-020:ID_NOT_PRODUCT_OR_RISKPOOL"); require(fractionalFee <= FRACTIONAL_FEE_MAX, "ERROR:TRS-021:FRACIONAL_FEE_TOO_BIG"); return FeeSpecification( componentId, fixedFee, fractionalFee, feeCalculationData, block.timestamp, // solhint-disable-line block.timestamp // solhint-disable-line ); } function setPremiumFees(FeeSpecification calldata feeSpec) external override whenNotSuspended onlyInstanceOperator { require(_component.isProduct(feeSpec.componentId), "ERROR:TRS-022:NOT_PRODUCT"); // record original creation timestamp uint256 originalCreatedAt = _fees[feeSpec.componentId].createdAt; _fees[feeSpec.componentId] = feeSpec; // set original creation timestamp if fee spec already existed if (originalCreatedAt > 0) { _fees[feeSpec.componentId].createdAt = originalCreatedAt; } emit LogTreasuryPremiumFeesSet ( feeSpec.componentId, feeSpec.fixedFee, feeSpec.fractionalFee); } function setCapitalFees(FeeSpecification calldata feeSpec) external override whenNotSuspended onlyInstanceOperator { require(_component.isRiskpool(feeSpec.componentId), "ERROR:TRS-023:NOT_RISKPOOL"); // record original creation timestamp uint256 originalCreatedAt = _fees[feeSpec.componentId].createdAt; _fees[feeSpec.componentId] = feeSpec; // set original creation timestamp if fee spec already existed if (originalCreatedAt > 0) { _fees[feeSpec.componentId].createdAt = originalCreatedAt; } emit LogTreasuryCapitalFeesSet ( feeSpec.componentId, feeSpec.fixedFee, feeSpec.fractionalFee); } function calculateFee(uint256 componentId, uint256 amount) public view returns(uint256 feeAmount, uint256 netAmount) { FeeSpecification memory feeSpec = getFeeSpecification(componentId); require(feeSpec.createdAt > 0, "ERROR:TRS-024:FEE_SPEC_UNDEFINED"); feeAmount = _calculateFee(feeSpec, amount); netAmount = amount - feeAmount; } /* * Process the remaining premium by calculating the remaining amount, the fees for that amount and * then transfering the fees to the instance wallet and the net premium remaining to the riskpool. * This will revert if no fee structure is defined. */ function processPremium(bytes32 processId) external override whenNotSuspended onlyPolicyFlow("Treasury") returns( bool success, uint256 feeAmount, uint256 netPremiumAmount ) { IPolicy.Policy memory policy = _policy.getPolicy(processId); if (policy.premiumPaidAmount < policy.premiumExpectedAmount) { (success, feeAmount, netPremiumAmount) = processPremium(processId, policy.premiumExpectedAmount - policy.premiumPaidAmount); } } /* * Process the premium by calculating the fees for the amount and * then transfering the fees to the instance wallet and the net premium to the riskpool. * This will revert if no fee structure is defined. */ function processPremium(bytes32 processId, uint256 amount) public override whenNotSuspended instanceWalletDefined riskpoolWalletDefinedForProcess(processId) onlyPolicyFlow("Treasury") returns( bool success, uint256 feeAmount, uint256 netAmount ) { IPolicy.Policy memory policy = _policy.getPolicy(processId); require( policy.premiumPaidAmount + amount <= policy.premiumExpectedAmount, "ERROR:TRS-030:AMOUNT_TOO_BIG" ); IPolicy.Metadata memory metadata = _policy.getMetadata(processId); (feeAmount, netAmount) = calculateFee(metadata.productId, amount); // check if allowance covers requested amount IERC20 token = getComponentToken(metadata.productId); if (token.allowance(metadata.owner, address(this)) < amount) { success = false; return (success, feeAmount, netAmount); } // collect premium fees success = TransferHelper.unifiedTransferFrom(token, metadata.owner, _instanceWalletAddress, feeAmount); emit LogTreasuryFeesTransferred(metadata.owner, _instanceWalletAddress, feeAmount); require(success, "ERROR:TRS-031:FEE_TRANSFER_FAILED"); // transfer premium net amount to riskpool for product // actual transfer of net premium to riskpool (uint256 riskpoolId, address riskpoolWalletAddress) = _getRiskpoolWallet(processId); success = TransferHelper.unifiedTransferFrom(token, metadata.owner, riskpoolWalletAddress, netAmount); emit LogTreasuryPremiumTransferred(metadata.owner, riskpoolWalletAddress, netAmount); require(success, "ERROR:TRS-032:PREMIUM_TRANSFER_FAILED"); emit LogTreasuryPremiumProcessed(processId, amount); } function processPayout(bytes32 processId, uint256 payoutId) external override whenNotSuspended instanceWalletDefined riskpoolWalletDefinedForProcess(processId) onlyPolicyFlow("Treasury") returns( uint256 feeAmount, uint256 netPayoutAmount ) { IPolicy.Payout memory payout = _policy.getPayout(processId, payoutId); require( payout.state == IPolicy.PayoutState.Expected, "ERROR:TRS-040:PAYOUT_ALREADY_PROCESSED" ); IPolicy.Metadata memory metadata = _policy.getMetadata(processId); IERC20 token = getComponentToken(metadata.productId); (uint256 riskpoolId, address riskpoolWalletAddress) = _getRiskpoolWallet(processId); require( token.balanceOf(riskpoolWalletAddress) >= payout.amount, "ERROR:TRS-042:RISKPOOL_WALLET_BALANCE_TOO_SMALL" ); require( token.allowance(riskpoolWalletAddress, address(this)) >= payout.amount, "ERROR:TRS-043:PAYOUT_ALLOWANCE_TOO_SMALL" ); // actual payout to policy holder bool success = TransferHelper.unifiedTransferFrom(token, riskpoolWalletAddress, metadata.owner, payout.amount); feeAmount = 0; netPayoutAmount = payout.amount; emit LogTreasuryPayoutTransferred(riskpoolWalletAddress, metadata.owner, payout.amount); require(success, "ERROR:TRS-044:PAYOUT_TRANSFER_FAILED"); emit LogTreasuryPayoutProcessed(riskpoolId, metadata.owner, payout.amount); } function processCapital(uint256 bundleId, uint256 capitalAmount) external override whenNotSuspended instanceWalletDefined riskpoolWalletDefinedForBundle(bundleId) onlyRiskpoolService returns( uint256 feeAmount, uint256 netCapitalAmount ) { // obtain relevant fee specification IBundle.Bundle memory bundle = _bundle.getBundle(bundleId); address bundleOwner = _bundle.getOwner(bundleId); FeeSpecification memory feeSpec = getFeeSpecification(bundle.riskpoolId); require(feeSpec.createdAt > 0, "ERROR:TRS-050:FEE_SPEC_UNDEFINED"); // obtain relevant token for product/riskpool pair IERC20 token = _componentToken[bundle.riskpoolId]; // calculate fees and net capital feeAmount = _calculateFee(feeSpec, capitalAmount); netCapitalAmount = capitalAmount - feeAmount; // check balance and allowance before starting any transfers require(token.balanceOf(bundleOwner) >= capitalAmount, "ERROR:TRS-052:BALANCE_TOO_SMALL"); require(token.allowance(bundleOwner, address(this)) >= capitalAmount, "ERROR:TRS-053:CAPITAL_TRANSFER_ALLOWANCE_TOO_SMALL"); bool success = TransferHelper.unifiedTransferFrom(token, bundleOwner, _instanceWalletAddress, feeAmount); emit LogTreasuryFeesTransferred(bundleOwner, _instanceWalletAddress, feeAmount); require(success, "ERROR:TRS-054:FEE_TRANSFER_FAILED"); // transfer net capital address riskpoolWallet = getRiskpoolWallet(bundle.riskpoolId); success = TransferHelper.unifiedTransferFrom(token, bundleOwner, riskpoolWallet, netCapitalAmount); emit LogTreasuryCapitalTransferred(bundleOwner, riskpoolWallet, netCapitalAmount); require(success, "ERROR:TRS-055:CAPITAL_TRANSFER_FAILED"); emit LogTreasuryCapitalProcessed(bundle.riskpoolId, bundleId, capitalAmount); } function processWithdrawal(uint256 bundleId, uint256 amount) external override whenNotSuspended instanceWalletDefined riskpoolWalletDefinedForBundle(bundleId) onlyRiskpoolService returns( uint256 feeAmount, uint256 netAmount ) { // obtain relevant bundle info IBundle.Bundle memory bundle = _bundle.getBundle(bundleId); require( bundle.capital >= bundle.lockedCapital + amount || (bundle.lockedCapital == 0 && bundle.balance >= amount), "ERROR:TRS-060:CAPACITY_OR_BALANCE_SMALLER_THAN_WITHDRAWAL" ); // obtain relevant token for product/riskpool pair address riskpoolWallet = getRiskpoolWallet(bundle.riskpoolId); address bundleOwner = _bundle.getOwner(bundleId); IERC20 token = _componentToken[bundle.riskpoolId]; require( token.balanceOf(riskpoolWallet) >= amount, "ERROR:TRS-061:RISKPOOL_WALLET_BALANCE_TOO_SMALL" ); require( token.allowance(riskpoolWallet, address(this)) >= amount, "ERROR:TRS-062:WITHDRAWAL_ALLOWANCE_TOO_SMALL" ); // TODO consider to introduce withdrawal fees // ideally symmetrical reusing capital fee spec for riskpool feeAmount = 0; netAmount = amount; bool success = TransferHelper.unifiedTransferFrom(token, riskpoolWallet, bundleOwner, netAmount); emit LogTreasuryWithdrawalTransferred(riskpoolWallet, bundleOwner, netAmount); require(success, "ERROR:TRS-063:WITHDRAWAL_TRANSFER_FAILED"); emit LogTreasuryWithdrawalProcessed(bundle.riskpoolId, bundleId, netAmount); } function getComponentToken(uint256 componentId) public override view returns(IERC20 token) { require(_component.isProduct(componentId) || _component.isRiskpool(componentId), "ERROR:TRS-070:NOT_PRODUCT_OR_RISKPOOL"); return _componentToken[componentId]; } function getFeeSpecification(uint256 componentId) public override view returns(FeeSpecification memory) { return _fees[componentId]; } function getFractionFullUnit() public override pure returns(uint256) { return FRACTION_FULL_UNIT; } function getInstanceWallet() public override view returns(address) { return _instanceWalletAddress; } function getRiskpoolWallet(uint256 riskpoolId) public override view returns(address) { return _riskpoolWallet[riskpoolId]; } function _calculatePremiumFee( FeeSpecification memory feeSpec, bytes32 processId ) internal view returns ( IPolicy.Application memory application, uint256 feeAmount ) { application = _policy.getApplication(processId); feeAmount = _calculateFee(feeSpec, application.premiumAmount); } function _calculateFee( FeeSpecification memory feeSpec, uint256 amount ) internal pure returns (uint256 feeAmount) { if (feeSpec.feeCalculationData.length > 0) { revert("ERROR:TRS-090:FEE_CALCULATION_DATA_NOT_SUPPORTED"); } // start with fixed fee feeAmount = feeSpec.fixedFee; // add fractional fee on top if (feeSpec.fractionalFee > 0) { feeAmount += (feeSpec.fractionalFee * amount) / FRACTION_FULL_UNIT; } // require that fee is smaller than amount require(feeAmount < amount, "ERROR:TRS-091:FEE_TOO_BIG"); } function _getRiskpoolWallet(bytes32 processId) internal view returns(uint256 riskpoolId, address riskpoolWalletAddress) { IPolicy.Metadata memory metadata = _policy.getMetadata(processId); riskpoolId = _pool.getRiskPoolForProduct(metadata.productId); require(riskpoolId > 0, "ERROR:TRS-092:PRODUCT_WITHOUT_RISKPOOL"); riskpoolWalletAddress = _riskpoolWallet[riskpoolId]; } }
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.2; import "IERC20.sol"; // inspired/informed by // https://soliditydeveloper.com/safe-erc20 // https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.7.3/contracts/token/ERC20/ERC20.sol // https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.7.3/contracts/token/ERC20/utils/SafeERC20.sol // https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.7.3/contracts/utils/Address.sol // https://github.com/Uniswap/solidity-lib/blob/master/contracts/libraries/TransferHelper.sol library TransferHelper { event LogTransferHelperInputValidation1Failed(bool tokenIsContract, address from, address to); event LogTransferHelperInputValidation2Failed(uint256 balance, uint256 allowance); event LogTransferHelperCallFailed(bool callSuccess, uint256 returnDataLength, bytes returnData); function unifiedTransferFrom( IERC20 token, address from, address to, uint256 value ) internal returns(bool success) { // input validation step 1 address tokenAddress = address(token); bool tokenIsContract = (tokenAddress.code.length > 0); if (from == address(0) || to == address (0) || !tokenIsContract) { emit LogTransferHelperInputValidation1Failed(tokenIsContract, from, to); return false; } // input validation step 2 uint256 balance = token.balanceOf(from); uint256 allowance = token.allowance(from, address(this)); if (balance < value || allowance < value) { emit LogTransferHelperInputValidation2Failed(balance, allowance); return false; } // low-level call to transferFrom // bytes4(keccak256(bytes('transferFrom(address,address,uint256)'))); (bool callSuccess, bytes memory data) = address(token).call( abi.encodeWithSelector( 0x23b872dd, from, to, value)); success = callSuccess && (false || data.length == 0 || (data.length == 32 && abi.decode(data, (bool)))); if (!success) { emit LogTransferHelperCallFailed(callSuccess, data.length, data); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); }
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.2; import "IERC20.sol"; interface ITreasury { event LogTreasurySuspended(); event LogTreasuryResumed(); event LogTreasuryProductTokenSet(uint256 productId, uint256 riskpoolId, address erc20Address); event LogTreasuryInstanceWalletSet(address walletAddress); event LogTreasuryRiskpoolWalletSet(uint256 riskpoolId, address walletAddress); event LogTreasuryPremiumFeesSet(uint256 productId, uint256 fixedFee, uint256 fractionalFee); event LogTreasuryCapitalFeesSet(uint256 riskpoolId, uint256 fixedFee, uint256 fractionalFee); event LogTreasuryPremiumTransferred(address from, address riskpoolWalletAddress, uint256 amount); event LogTreasuryPayoutTransferred(address riskpoolWalletAddress, address to, uint256 amount); event LogTreasuryCapitalTransferred(address from, address riskpoolWalletAddress, uint256 amount); event LogTreasuryFeesTransferred(address from, address instanceWalletAddress, uint256 amount); event LogTreasuryWithdrawalTransferred(address riskpoolWalletAddress, address to, uint256 amount); event LogTreasuryPremiumProcessed(bytes32 processId, uint256 amount); event LogTreasuryPayoutProcessed(uint256 riskpoolId, address to, uint256 amount); event LogTreasuryCapitalProcessed(uint256 riskpoolId, uint256 bundleId, uint256 amount); event LogTreasuryWithdrawalProcessed(uint256 riskpoolId, uint256 bundleId, uint256 amount); struct FeeSpecification { uint256 componentId; uint256 fixedFee; uint256 fractionalFee; bytes feeCalculationData; uint256 createdAt; uint256 updatedAt; } function setProductToken(uint256 productId, address erc20Address) external; function setInstanceWallet(address instanceWalletAddress) external; function setRiskpoolWallet(uint256 riskpoolId, address riskpoolWalletAddress) external; function createFeeSpecification( uint256 componentId, uint256 fixedFee, uint256 fractionalFee, bytes calldata feeCalculationData ) external view returns(FeeSpecification memory feeSpec); function setPremiumFees(FeeSpecification calldata feeSpec) external; function setCapitalFees(FeeSpecification calldata feeSpec) external; function processPremium(bytes32 processId) external returns( bool success, uint256 feeAmount, uint256 netPremiumAmount ); function processPremium(bytes32 processId, uint256 amount) external returns( bool success, uint256 feeAmount, uint256 netPremiumAmount ); function processPayout(bytes32 processId, uint256 payoutId) external returns( uint256 feeAmount, uint256 netPayoutAmount ); function processCapital(uint256 bundleId, uint256 capitalAmount) external returns( uint256 feeAmount, uint256 netCapitalAmount ); function processWithdrawal(uint256 bundleId, uint256 amount) external returns( uint256 feeAmount, uint256 netAmount ); function getComponentToken(uint256 componentId) external view returns(IERC20 token); function getFeeSpecification(uint256 componentId) external view returns(FeeSpecification memory feeSpecification); function getFractionFullUnit() external view returns(uint256); function getInstanceWallet() external view returns(address instanceWalletAddress); function getRiskpoolWallet(uint256 riskpoolId) external view returns(address riskpoolWalletAddress); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol) pragma solidity ^0.8.0; import "Context.sol"; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract Pausable is Context { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ constructor() { _paused = false; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { _requireNotPaused(); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { _requirePaused(); _; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Throws if the contract is paused. */ function _requireNotPaused() internal view virtual { require(!paused(), "Pausable: paused"); } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { require(paused(), "Pausable: not paused"); } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } }
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.2; import "AccessController.sol"; import "BundleController.sol"; import "ComponentController.sol"; import "PoolController.sol"; import "TreasuryModule.sol"; import "CoreController.sol"; import "TestProduct.sol"; import "BundleToken.sol"; import "IComponent.sol"; import "IProduct.sol"; import "IQuery.sol"; import "ITreasury.sol"; import "IInstanceOperatorService.sol"; import "Ownable.sol"; contract InstanceOperatorService is IInstanceOperatorService, CoreController, Ownable { ComponentController private _component; PoolController private _pool; TreasuryModule private _treasury; modifier onlyInstanceOperatorAddress() { require(owner() == _msgSender(), "ERROR:IOS-001:NOT_INSTANCE_OPERATOR"); _; } function _afterInitialize() internal override onlyInitializing { _component = ComponentController(_getContractAddress("Component")); _pool = PoolController(_getContractAddress("Pool")); _treasury = TreasuryModule(_getContractAddress("Treasury")); _transferOwnership(_msgSender()); _linkBundleModuleToBundleToken(); _setDefaultAdminRole(); } function _setDefaultAdminRole() private { AccessController access = AccessController(_getContractAddress("Access")); access.setDefaultAdminRole(address(this)); } function _linkBundleModuleToBundleToken() private { BundleToken token = BundleToken(_getContractAddress("BundleToken")); address bundleAddress = _getContractAddress("Bundle"); token.setBundleModule(bundleAddress); } /* registry */ function prepareRelease(bytes32 _newRelease) external override onlyInstanceOperatorAddress { _registry.prepareRelease(_newRelease); } function register(bytes32 _contractName, address _contractAddress) external override onlyInstanceOperatorAddress { _registry.register(_contractName, _contractAddress); } function deregister(bytes32 _contractName) external override onlyInstanceOperatorAddress { _registry.deregister(_contractName); } function registerInRelease( bytes32 _release, bytes32 _contractName, address _contractAddress ) external override onlyInstanceOperatorAddress { _registry.registerInRelease(_release, _contractName, _contractAddress); } function deregisterInRelease(bytes32 _release, bytes32 _contractName) external override onlyInstanceOperatorAddress { _registry.deregisterInRelease(_release, _contractName); } /* access */ function createRole(bytes32 _role) external override onlyInstanceOperatorAddress { _access.addRole(_role); } function invalidateRole(bytes32 _role) external override onlyInstanceOperatorAddress { _access.invalidateRole(_role); } function grantRole(bytes32 role, address principal) external override onlyInstanceOperatorAddress { _access.grantRole(role, principal); } function revokeRole(bytes32 role, address principal) external override onlyInstanceOperatorAddress { _access.revokeRole(role, principal); } /* component */ function approve(uint256 id) external override onlyInstanceOperatorAddress { _component.approve(id); if (_component.isProduct(id)) { IComponent component = _component.getComponent(id); IProduct product = IProduct(address(component)); _pool.setRiskpoolForProduct( id, product.getRiskpoolId()); } } function decline(uint256 id) external override onlyInstanceOperatorAddress { _component.decline(id); } function suspend(uint256 id) external override onlyInstanceOperatorAddress { _component.suspend(id); } function resume(uint256 id) external override onlyInstanceOperatorAddress { _component.resume(id); } function archive(uint256 id) external override onlyInstanceOperatorAddress { _component.archiveFromInstanceOperator(id); } // service staking // TODO implement setDefaultStaking staking function setDefaultStaking( uint16 componentType, bytes calldata data ) external override onlyInstanceOperatorAddress { revert("ERROR:IOS-010:IMPLEMENATION_MISSING"); } // TODO implement adjustStakingRequirements staking function adjustStakingRequirements( uint256 id, bytes calldata data ) external override onlyInstanceOperatorAddress { revert("ERROR:IOS-011:IMPLEMENATION_MISSING"); } /* treasury */ function suspendTreasury() external override onlyInstanceOperatorAddress { _treasury.suspend(); } function resumeTreasury() external override onlyInstanceOperatorAddress { _treasury.resume(); } function setInstanceWallet(address walletAddress) external override onlyInstanceOperatorAddress { _treasury.setInstanceWallet(walletAddress); } function setRiskpoolWallet(uint256 riskpoolId, address riskpoolWalletAddress) external override onlyInstanceOperatorAddress { _treasury.setRiskpoolWallet(riskpoolId, riskpoolWalletAddress); } function setProductToken(uint256 productId, address erc20Address) external override onlyInstanceOperatorAddress { _treasury.setProductToken(productId, erc20Address); } function createFeeSpecification( uint256 componentId, uint256 fixedFee, uint256 fractionalFee, bytes calldata feeCalculationData ) external override view returns(ITreasury.FeeSpecification memory) { return _treasury.createFeeSpecification( componentId, fixedFee, fractionalFee, feeCalculationData ); } function setPremiumFees(ITreasury.FeeSpecification calldata feeSpec) external override onlyInstanceOperatorAddress { _treasury.setPremiumFees(feeSpec); } function setCapitalFees(ITreasury.FeeSpecification calldata feeSpec) external override onlyInstanceOperatorAddress { _treasury.setCapitalFees(feeSpec); } }
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.2; import "CoreController.sol"; import "IAccess.sol"; import "AccessControlEnumerable.sol"; import "Initializable.sol"; contract AccessController is IAccess, CoreController, AccessControlEnumerable { // 0xe984cfd1d1fa34f80e24ddb2a60c8300359d79eee44555bc35c106eb020394cd bytes32 public constant PRODUCT_OWNER_ROLE = keccak256("PRODUCT_OWNER_ROLE"); // 0xd26b4cd59ffa91e4599f3d18b02fcd5ffb06e03216f3ee5f25f68dc75cbbbaa2 bytes32 public constant ORACLE_PROVIDER_ROLE = keccak256("ORACLE_PROVIDER_ROLE"); // 0x3c4cdb47519f2f89924ebeb1ee7a8a43b8b00120826915726460bb24576012fd bytes32 public constant RISKPOOL_KEEPER_ROLE = keccak256("RISKPOOL_KEEPER_ROLE"); mapping(bytes32 => bool) public validRole; bool private _defaultAdminSet; function _afterInitialize() internal override { // add product owner, oracle provider and riskpool keeper roles _populateValidRoles(); } function _getName() internal override pure returns(bytes32) { return "Access"; } // IMPORTANT check the setting of the default admin role // after the deployment of a GIF instance. // this method is called in the deployment of // the instance operator proxy/controller function setDefaultAdminRole(address defaultAdmin) external { require(!_defaultAdminSet, "ERROR:ACL-001:ADMIN_ROLE_ALREADY_SET"); _defaultAdminSet = true; _grantRole(DEFAULT_ADMIN_ROLE, defaultAdmin); } //--- manage role ownership ---------------------------------------------// function grantRole(bytes32 role, address principal) public override(IAccessControl, IAccess) onlyInstanceOperator { require(validRole[role], "ERROR:ACL-002:ROLE_UNKNOWN_OR_INVALID"); AccessControl.grantRole(role, principal); } function revokeRole(bytes32 role, address principal) public override(IAccessControl, IAccess) onlyInstanceOperator { AccessControl.revokeRole(role, principal); } function renounceRole(bytes32 role, address principal) public override(IAccessControl, IAccess) { AccessControl.renounceRole(role, principal); } //--- manage roles ------------------------------------------------------// function addRole(bytes32 role) public override onlyInstanceOperator { require(!validRole[role], "ERROR:ACL-003:ROLE_EXISTING_AND_VALID"); validRole[role] = true; } function invalidateRole(bytes32 role) public override onlyInstanceOperator { require(validRole[role], "ERROR:ACL-004:ROLE_UNKNOWN_OR_INVALID"); validRole[role] = false; } function hasRole(bytes32 role, address principal) public view override(IAccessControl, IAccess) returns(bool) { return super.hasRole(role, principal); } function getDefaultAdminRole() public pure override returns(bytes32) { return DEFAULT_ADMIN_ROLE; } function getProductOwnerRole() public pure override returns(bytes32) { return PRODUCT_OWNER_ROLE; } function getOracleProviderRole() public pure override returns(bytes32) { return ORACLE_PROVIDER_ROLE; } function getRiskpoolKeeperRole() public pure override returns(bytes32) { return RISKPOOL_KEEPER_ROLE; } function _populateValidRoles() private { validRole[PRODUCT_OWNER_ROLE] = true; validRole[ORACLE_PROVIDER_ROLE] = true; validRole[RISKPOOL_KEEPER_ROLE] = true; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControlEnumerable.sol) pragma solidity ^0.8.0; import "IAccessControlEnumerable.sol"; import "AccessControl.sol"; import "EnumerableSet.sol"; /** * @dev Extension of {AccessControl} that allows enumerating the members of each role. */ abstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessControl { using EnumerableSet for EnumerableSet.AddressSet; mapping(bytes32 => EnumerableSet.AddressSet) private _roleMembers; /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControlEnumerable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns one of the accounts that have `role`. `index` must be a * value between 0 and {getRoleMemberCount}, non-inclusive. * * Role bearers are not sorted in any particular way, and their ordering may * change at any point. * * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure * you perform all queries on the same block. See the following * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] * for more information. */ function getRoleMember(bytes32 role, uint256 index) public view virtual override returns (address) { return _roleMembers[role].at(index); } /** * @dev Returns the number of accounts that have `role`. Can be used * together with {getRoleMember} to enumerate all bearers of a role. */ function getRoleMemberCount(bytes32 role) public view virtual override returns (uint256) { return _roleMembers[role].length(); } /** * @dev Overload {_grantRole} to track enumerable memberships */ function _grantRole(bytes32 role, address account) internal virtual override { super._grantRole(role, account); _roleMembers[role].add(account); } /** * @dev Overload {_revokeRole} to track enumerable memberships */ function _revokeRole(bytes32 role, address account) internal virtual override { super._revokeRole(role, account); _roleMembers[role].remove(account); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol) pragma solidity ^0.8.0; import "IAccessControl.sol"; /** * @dev External interface of AccessControlEnumerable declared to support ERC165 detection. */ interface IAccessControlEnumerable is IAccessControl { /** * @dev Returns one of the accounts that have `role`. `index` must be a * value between 0 and {getRoleMemberCount}, non-inclusive. * * Role bearers are not sorted in any particular way, and their ordering may * change at any point. * * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure * you perform all queries on the same block. See the following * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] * for more information. */ function getRoleMember(bytes32 role, uint256 index) external view returns (address); /** * @dev Returns the number of accounts that have `role`. Can be used * together with {getRoleMember} to enumerate all bearers of a role. */ function getRoleMemberCount(bytes32 role) external view returns (uint256); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol) pragma solidity ^0.8.0; /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControl { /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (access/AccessControl.sol) pragma solidity ^0.8.0; import "IAccessControl.sol"; import "Context.sol"; import "Strings.sol"; import "ERC165.sol"; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ``` * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ``` * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. */ abstract contract AccessControl is Context, IAccessControl, ERC165 { struct RoleData { mapping(address => bool) members; bytes32 adminRole; } mapping(bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with a standardized message including the required role. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ * * _Available since v4.1._ */ modifier onlyRole(bytes32 role) { _checkRole(role); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view virtual override returns (bool) { return _roles[role].members[account]; } /** * @dev Revert with a standard message if `_msgSender()` is missing `role`. * Overriding this function changes the behavior of the {onlyRole} modifier. * * Format of the revert message is described in {_checkRole}. * * _Available since v4.6._ */ function _checkRole(bytes32 role) internal view virtual { _checkRole(role, _msgSender()); } /** * @dev Revert with a standard message if `account` is missing `role`. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ */ function _checkRole(bytes32 role, address account) internal view virtual { if (!hasRole(role, account)) { revert( string( abi.encodePacked( "AccessControl: account ", Strings.toHexString(uint160(account), 20), " is missing role ", Strings.toHexString(uint256(role), 32) ) ) ); } } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleGranted} event. */ function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleRevoked} event. */ function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been revoked `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. * * May emit a {RoleRevoked} event. */ function renounceRole(bytes32 role, address account) public virtual override { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * May emit a {RoleGranted} event. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== * * NOTE: This function is deprecated in favor of {_grantRole}. */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = getRoleAdmin(role); _roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } /** * @dev Grants `role` to `account`. * * Internal function without access restriction. * * May emit a {RoleGranted} event. */ function _grantRole(bytes32 role, address account) internal virtual { if (!hasRole(role, account)) { _roles[role].members[account] = true; emit RoleGranted(role, account, _msgSender()); } } /** * @dev Revokes `role` from `account`. * * Internal function without access restriction. * * May emit a {RoleRevoked} event. */ function _revokeRole(bytes32 role, address account) internal virtual { if (hasRole(role, account)) { _roles[role].members[account] = false; emit RoleRevoked(role, account, _msgSender()); } } }
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.2; import "IPolicy.sol"; import "IProductService.sol"; import "IInstanceService.sol"; import "Product.sol"; import "ERC20.sol"; contract TestProduct is Product { bytes32 public constant POLICY_FLOW = "PolicyDefaultFlow"; string public constant ORACLE_CALLBACK_METHOD_NAME = "oracleCallback"; address private _capitalOwner; uint256 private _testOracleId; uint256 private _testRiskpoolId; bytes32 [] private _applications; bytes32 [] private _policies; uint256 private _claims; mapping(bytes32 => uint256) private _policyIdToClaimId; mapping(bytes32 => uint256) private _policyIdToPayoutId; event LogTestProductFundingReceived(address sender, uint256 amount); event LogTestOracleCallbackReceived(uint256 requestId, bytes32 policyId, bytes response); constructor( bytes32 productName, address tokenAddress, address capitalOwner, uint256 oracleId, uint256 riskpoolId, address registryAddress ) Product(productName, tokenAddress, POLICY_FLOW, riskpoolId, registryAddress) { require(tokenAddress != address(0), "ERROR:TI-2:TOKEN_ADDRESS_ZERO"); _capitalOwner = capitalOwner; _testOracleId = oracleId; _testRiskpoolId = riskpoolId; } function applyForPolicy( uint256 premium, uint256 sumInsured, bytes calldata metaData, bytes calldata applicationData ) external payable returns (bytes32 processId) { address payable policyHolder = payable(_msgSender()); processId = _newApplication( policyHolder, premium, sumInsured, metaData, applicationData); _applications.push(processId); bool success = _underwrite(processId); if (success) { _policies.push(processId); } } function applyForPolicy( address payable policyHolder, uint256 premium, uint256 sumInsured, bytes calldata metaData, bytes calldata applicationData ) external payable returns (bytes32 processId) { processId = _newApplication( policyHolder, premium, sumInsured, metaData, applicationData); _applications.push(processId); bool success = _underwrite(processId); if (success) { _policies.push(processId); } } function newAppliation( uint256 premium, uint256 sumInsured, bytes calldata metaData, bytes calldata applicationData ) external payable returns (bytes32 processId) { address payable policyHolder = payable(_msgSender()); processId = _newApplication( policyHolder, premium, sumInsured, metaData, applicationData); _applications.push(processId); } function revoke(bytes32 processId) external onlyPolicyHolder(processId) { _revoke(processId); } function decline(bytes32 processId) external onlyOwner { _decline(processId); } function underwrite(bytes32 processId) external onlyOwner { bool success = _underwrite(processId); if (success) { _policies.push(processId); } } function collectPremium(bytes32 policyId) external onlyOwner returns(bool success, uint256 fee, uint256 netPremium) { (success, fee, netPremium) = _collectPremium(policyId); } function collectPremium(bytes32 policyId, uint256 amount) external onlyOwner returns(bool success, uint256 fee, uint256 netPremium) { (success, fee, netPremium) = _collectPremium(policyId, amount); } function expire(bytes32 policyId) external onlyOwner { _expire(policyId); } function close(bytes32 policyId) external onlyOwner { _close(policyId); } function submitClaim(bytes32 policyId, uint256 claimAmount) external onlyPolicyHolder(policyId) returns(uint256 claimId) { // increase claims counter // the oracle business logic will use this counter value // to determine if the claim is linked to a loss event or not _claims++; // claim application claimId = _newClaim(policyId, claimAmount, ""); _policyIdToClaimId[policyId] = claimId; // Request response to greeting via oracle call bool immediateResponse = true; bytes memory queryData = abi.encode(_claims, immediateResponse); _request( policyId, queryData, ORACLE_CALLBACK_METHOD_NAME, _testOracleId ); } function submitClaimNoOracle(bytes32 policyId, uint256 claimAmount) external onlyPolicyHolder(policyId) returns(uint256 claimId) { // increase claims counter // the oracle business logic will use this counter value // to determine if the claim is linked to a loss event or not _claims++; // claim application claimId = _newClaim(policyId, claimAmount, ""); _policyIdToClaimId[policyId] = claimId; } function submitClaimWithDeferredResponse(bytes32 policyId, uint256 claimAmount) external onlyPolicyHolder(policyId) returns(uint256 claimId, uint256 requestId) { // increase claims counter // the oracle business logic will use this counter value // to determine if the claim is linked to a loss event or not _claims++; // claim application claimId = _newClaim(policyId, claimAmount, ""); _policyIdToClaimId[policyId] = claimId; // Request response to greeting via oracle call bool immediateResponse = false; bytes memory queryData = abi.encode(_claims, immediateResponse); requestId = _request( policyId, queryData, ORACLE_CALLBACK_METHOD_NAME, _testOracleId ); } function confirmClaim( bytes32 policyId, uint256 claimId, uint256 confirmedAmount ) external onlyOwner { _confirmClaim(policyId, claimId, confirmedAmount); } function declineClaim( bytes32 policyId, uint256 claimId ) external onlyOwner { _declineClaim(policyId, claimId); } function closeClaim( bytes32 policyId, uint256 claimId ) external onlyOwner { _closeClaim(policyId, claimId); } function createPayout( bytes32 policyId, uint256 claimId, uint256 payoutAmount ) external onlyOwner returns(uint256 payoutId) { payoutId = _newPayout( policyId, claimId, payoutAmount, abi.encode(0)); _processPayout(policyId, payoutId); } function newPayout( bytes32 policyId, uint256 claimId, uint256 payoutAmount ) external onlyOwner returns(uint256 payoutId) { payoutId = _newPayout( policyId, claimId, payoutAmount, abi.encode(0)); } function processPayout( bytes32 policyId, uint256 payoutId ) external onlyOwner { _processPayout(policyId, payoutId); } function oracleCallback( uint256 requestId, bytes32 policyId, bytes calldata responseData ) external onlyOracle { emit LogTestOracleCallbackReceived(requestId, policyId, responseData); // get oracle response data (bool isLossEvent) = abi.decode(responseData, (bool)); uint256 claimId = _policyIdToClaimId[policyId]; // claim handling if there is a loss if (isLossEvent) { // get policy and claims info for oracle response _getApplication(policyId); IPolicy.Claim memory claim = _getClaim(policyId, claimId); // specify payout data uint256 confirmedAmount = claim.claimAmount; _confirmClaim(policyId, claimId, confirmedAmount); // create payout record uint256 payoutAmount = confirmedAmount; bytes memory payoutData = abi.encode(0); uint256 payoutId = _newPayout(policyId, claimId, payoutAmount, payoutData); _policyIdToPayoutId[policyId] = payoutId; _processPayout(policyId, payoutId); // TODO refactor to payout using erc-20 token // actual transfer of funds for payout of claim // failing requires not visible when called via .call in querycontroller // policyHolder.transfer(payoutAmount); } else { _declineClaim(policyId, claimId); } } function getClaimId(bytes32 policyId) external view returns (uint256) { return _policyIdToClaimId[policyId]; } function getPayoutId(bytes32 policyId) external view returns (uint256) { return _policyIdToPayoutId[policyId]; } function applications() external view returns (uint256) { return _applications.length; } function policies() external view returns (uint256) { return _policies.length; } function claims() external view returns (uint256) { return _claims; } }
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.2; interface IProductService { function newApplication( address owner, uint256 premiumAmount, uint256 sumInsuredAmount, bytes calldata metaData, bytes calldata applicationData ) external returns(bytes32 processId); function collectPremium(bytes32 processId, uint256 amount) external returns( bool success, uint256 feeAmount, uint256 netPremiumAmount ); function adjustPremiumSumInsured( bytes32 processId, uint256 expectedPremiumAmount, uint256 sumInsuredAmount ) external; function revoke(bytes32 processId) external; function underwrite(bytes32 processId) external returns(bool success); function decline(bytes32 processId) external; function expire(bytes32 processId) external; function close(bytes32 processId) external; function newClaim( bytes32 processId, uint256 claimAmount, bytes calldata data ) external returns(uint256 claimId); function confirmClaim( bytes32 processId, uint256 claimId, uint256 confirmedAmount ) external; function declineClaim(bytes32 processId, uint256 claimId) external; function closeClaim(bytes32 processId, uint256 claimId) external; function newPayout( bytes32 processId, uint256 claimId, uint256 amount, bytes calldata data ) external returns(uint256 payoutId); function processPayout(bytes32 processId, uint256 payoutId) external returns( uint256 feeAmount, uint256 netPayoutAmount ); function request( bytes32 processId, bytes calldata data, string calldata callbackMethodName, address callbackContractAddress, uint256 responsibleOracleId ) external returns(uint256 requestId); function cancelRequest(uint256 requestId) external; }
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.2; import "IComponent.sol"; import "IBundle.sol"; import "IPolicy.sol"; import "IPool.sol"; import "IBundleToken.sol"; import "IComponentOwnerService.sol"; import "IInstanceOperatorService.sol"; import "IOracleService.sol"; import "IProductService.sol"; import "IRiskpoolService.sol"; import "IERC20.sol"; import "IERC721.sol"; interface IInstanceService { // instance function getChainId() external view returns(uint256 chainId); function getChainName() external view returns(string memory chainName); function getInstanceId() external view returns(bytes32 instanceId); function getInstanceOperator() external view returns(address instanceOperator); // registry function getComponentOwnerService() external view returns(IComponentOwnerService service); function getInstanceOperatorService() external view returns(IInstanceOperatorService service); function getOracleService() external view returns(IOracleService service); function getProductService() external view returns(IProductService service); function getRiskpoolService() external view returns(IRiskpoolService service); function contracts() external view returns (uint256 numberOfContracts); function contractName(uint256 idx) external view returns (bytes32 name); // access function getDefaultAdminRole() external view returns(bytes32 role); function getProductOwnerRole() external view returns(bytes32 role); function getOracleProviderRole() external view returns(bytes32 role); function getRiskpoolKeeperRole() external view returns(bytes32 role); function hasRole(bytes32 role, address principal) external view returns (bool roleIsAssigned); // component function products() external view returns(uint256 numberOfProducts); function oracles() external view returns(uint256 numberOfOracles); function riskpools() external view returns(uint256 numberOfRiskpools); function getComponentId(address componentAddress) external view returns(uint256 componentId); function getComponent(uint256 componentId) external view returns(IComponent component); function getComponentType(uint256 componentId) external view returns(IComponent.ComponentType componentType); function getComponentState(uint256 componentId) external view returns(IComponent.ComponentState componentState); // service staking function getStakingRequirements(uint256 componentId) external view returns(bytes memory data); function getStakedAssets(uint256 componentId) external view returns(bytes memory data); // riskpool function getRiskpool(uint256 riskpoolId) external view returns(IPool.Pool memory riskPool); function getFullCollateralizationLevel() external view returns (uint256); function getCapital(uint256 riskpoolId) external view returns(uint256 capitalAmount); function getTotalValueLocked(uint256 riskpoolId) external view returns(uint256 totalValueLockedAmount); function getCapacity(uint256 riskpoolId) external view returns(uint256 capacityAmount); function getBalance(uint256 riskpoolId) external view returns(uint256 balanceAmount); function activeBundles(uint256 riskpoolId) external view returns(uint256 numberOfActiveBundles); function getActiveBundleId(uint256 riskpoolId, uint256 bundleIdx) external view returns(uint256 bundleId); function getMaximumNumberOfActiveBundles(uint256 riskpoolId) external view returns(uint256 maximumNumberOfActiveBundles); // bundles function getBundleToken() external view returns(IBundleToken token); function bundles() external view returns(uint256 numberOfBundles); function getBundle(uint256 bundleId) external view returns(IBundle.Bundle memory bundle); function unburntBundles(uint256 riskpoolId) external view returns(uint256 numberOfUnburntBundles); // policy function processIds() external view returns(uint256 numberOfProcessIds); function getMetadata(bytes32 processId) external view returns(IPolicy.Metadata memory metadata); function getApplication(bytes32 processId) external view returns(IPolicy.Application memory application); function getPolicy(bytes32 processId) external view returns(IPolicy.Policy memory policy); function claims(bytes32 processId) external view returns(uint256 numberOfClaims); function payouts(bytes32 processId) external view returns(uint256 numberOfPayouts); function getClaim(bytes32 processId, uint256 claimId) external view returns (IPolicy.Claim memory claim); function getPayout(bytes32 processId, uint256 payoutId) external view returns (IPolicy.Payout memory payout); // treasury function getTreasuryAddress() external view returns(address treasuryAddress); function getInstanceWallet() external view returns(address walletAddress); function getRiskpoolWallet(uint256 riskpoolId) external view returns(address walletAddress); function getComponentToken(uint256 componentId) external view returns(IERC20 token); function getFeeFractionFullUnit() external view returns(uint256 fullUnit); }
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.2; import "IComponent.sol"; interface IComponentOwnerService { function propose(IComponent component) external; function stake(uint256 id) external; function withdraw(uint256 id) external; function pause(uint256 id) external; function unpause(uint256 id) external; function archive(uint256 id) external; }
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.2; import "ITreasury.sol"; interface IInstanceOperatorService { // registry function prepareRelease(bytes32 newRelease) external; function register(bytes32 contractName, address contractAddress) external; function deregister(bytes32 contractName) external; function registerInRelease(bytes32 release, bytes32 contractName, address contractAddress) external; function deregisterInRelease(bytes32 release, bytes32 contractName) external; // access function createRole(bytes32 role) external; function invalidateRole(bytes32 role) external; function grantRole(bytes32 role, address principal) external; function revokeRole(bytes32 role, address principal) external; // component function approve(uint256 id) external; function decline(uint256 id) external; function suspend(uint256 id) external; function resume(uint256 id) external; function archive(uint256 id) external; // service staking function setDefaultStaking(uint16 componentType, bytes calldata data) external; function adjustStakingRequirements(uint256 id, bytes calldata data) external; // treasury function suspendTreasury() external; function resumeTreasury() external; function setInstanceWallet(address walletAddress) external; function setRiskpoolWallet(uint256 riskpoolId, address walletAddress) external; function setProductToken(uint256 productId, address erc20Address) external; function setPremiumFees(ITreasury.FeeSpecification calldata feeSpec) external; function setCapitalFees(ITreasury.FeeSpecification calldata feeSpec) external; function createFeeSpecification( uint256 componentId, uint256 fixedFee, uint256 fractionalFee, bytes calldata feeCalculationData ) external view returns(ITreasury.FeeSpecification memory); }
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.2; interface IOracleService { function respond(uint256 requestId, bytes calldata data) external; }
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.2; interface IRiskpoolService { function registerRiskpool( address wallet, address erc20Token, uint256 collateralization, uint256 sumOfSumInsuredCap ) external; function createBundle(address owner_, bytes calldata filter_, uint256 amount_) external returns(uint256 bundleId); function fundBundle(uint256 bundleId, uint256 amount) external returns(uint256 netAmount); function defundBundle(uint256 bundleId, uint256 amount) external returns(uint256 netAmount); function lockBundle(uint256 bundleId) external; function unlockBundle(uint256 bundleId) external; function closeBundle(uint256 bundleId) external; function burnBundle(uint256 bundleId) external; function collateralizePolicy(uint256 bundleId, bytes32 processId, uint256 collateralAmount) external; function processPremium(uint256 bundleId, bytes32 processId, uint256 amount) external; function processPayout(uint256 bundleId, bytes32 processId, uint256 amount) external; function releasePolicy(uint256 bundleId, bytes32 processId) external returns(uint256 collateralAmount); function setMaximumNumberOfActiveBundles(uint256 riskpoolId, uint256 maxNumberOfActiveBundles) external; }
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.2; import "IProduct.sol"; import "Component.sol"; import "IPolicy.sol"; import "IInstanceService.sol"; import "IProductService.sol"; abstract contract Product is IProduct, Component { address private _policyFlow; // policy flow contract to use for this procut address private _token; // erc20 token to use for this product uint256 private _riskpoolId; // id of riskpool responsible for this product IProductService internal _productService; IInstanceService internal _instanceService; modifier onlyPolicyHolder(bytes32 policyId) { address policyHolder = _instanceService.getMetadata(policyId).owner; require( _msgSender() == policyHolder, "ERROR:PRD-001:POLICY_OR_HOLDER_INVALID" ); _; } modifier onlyLicence { require( _msgSender() == _getContractAddress("Licence"), "ERROR:PRD-002:ACCESS_DENIED" ); _; } modifier onlyOracle { require( _msgSender() == _getContractAddress("Query"), "ERROR:PRD-003:ACCESS_DENIED" ); _; } constructor( bytes32 name, address token, bytes32 policyFlow, uint256 riskpoolId, address registry ) Component(name, ComponentType.Product, registry) { _token = token; _riskpoolId = riskpoolId; // TODO add validation for policy flow _policyFlow = _getContractAddress(policyFlow); _productService = IProductService(_getContractAddress("ProductService")); _instanceService = IInstanceService(_getContractAddress("InstanceService")); emit LogProductCreated(address(this)); } function getToken() public override view returns(address) { return _token; } function getPolicyFlow() public view override returns(address) { return _policyFlow; } function getRiskpoolId() public override view returns(uint256) { return _riskpoolId; } // default callback function implementations function _afterApprove() internal override { emit LogProductApproved(getId()); } function _afterPropose() internal override { emit LogProductProposed(getId()); } function _afterDecline() internal override { emit LogProductDeclined(getId()); } function _newApplication( address applicationOwner, uint256 premiumAmount, uint256 sumInsuredAmount, bytes memory metaData, bytes memory applicationData ) internal returns(bytes32 processId) { processId = _productService.newApplication( applicationOwner, premiumAmount, sumInsuredAmount, metaData, applicationData); } function _collectPremium(bytes32 processId) internal returns( bool success, uint256 feeAmount, uint256 netAmount ) { IPolicy.Policy memory policy = _getPolicy(processId); if (policy.premiumPaidAmount < policy.premiumExpectedAmount) { (success, feeAmount, netAmount) = _collectPremium( processId, policy.premiumExpectedAmount - policy.premiumPaidAmount ); } } function _collectPremium( bytes32 processId, uint256 amount ) internal returns( bool success, uint256 feeAmount, uint256 netAmount ) { (success, feeAmount, netAmount) = _productService.collectPremium(processId, amount); } function _adjustPremiumSumInsured( bytes32 processId, uint256 expectedPremiumAmount, uint256 sumInsuredAmount ) internal { _productService.adjustPremiumSumInsured(processId, expectedPremiumAmount, sumInsuredAmount); } function _revoke(bytes32 processId) internal { _productService.revoke(processId); } function _underwrite(bytes32 processId) internal returns(bool success) { success = _productService.underwrite(processId); } function _decline(bytes32 processId) internal { _productService.decline(processId); } function _expire(bytes32 processId) internal { _productService.expire(processId); } function _close(bytes32 processId) internal { _productService.close(processId); } function _newClaim( bytes32 processId, uint256 claimAmount, bytes memory data ) internal returns (uint256 claimId) { claimId = _productService.newClaim( processId, claimAmount, data); } function _confirmClaim( bytes32 processId, uint256 claimId, uint256 payoutAmount ) internal { _productService.confirmClaim( processId, claimId, payoutAmount); } function _declineClaim(bytes32 processId, uint256 claimId) internal { _productService.declineClaim(processId, claimId); } function _closeClaim(bytes32 processId, uint256 claimId) internal { _productService.closeClaim(processId, claimId); } function _newPayout( bytes32 processId, uint256 claimId, uint256 amount, bytes memory data ) internal returns(uint256 payoutId) { payoutId = _productService.newPayout(processId, claimId, amount, data); } function _processPayout( bytes32 processId, uint256 payoutId ) internal returns( uint256 feeAmount, uint256 netPayoutAmount ) { ( feeAmount, netPayoutAmount ) = _productService.processPayout(processId, payoutId); } function _request( bytes32 processId, bytes memory input, string memory callbackMethodName, uint256 responsibleOracleId ) internal returns (uint256 requestId) { requestId = _productService.request( processId, input, callbackMethodName, address(this), responsibleOracleId ); } function _cancelRequest(uint256 requestId) internal { _productService.cancelRequest(requestId); } function _getMetadata(bytes32 processId) internal view returns (IPolicy.Metadata memory metadata) { return _instanceService.getMetadata(processId); } function _getApplication(bytes32 processId) internal view returns (IPolicy.Application memory application) { return _instanceService.getApplication(processId); } function _getPolicy(bytes32 processId) internal view returns (IPolicy.Policy memory policy) { return _instanceService.getPolicy(processId); } function _getClaim(bytes32 processId, uint256 claimId) internal view returns (IPolicy.Claim memory claim) { return _instanceService.getClaim(processId, claimId); } function _getPayout(bytes32 processId, uint256 payoutId) internal view returns (IPolicy.Payout memory payout) { return _instanceService.getPayout(processId, payoutId); } function getApplicationDataStructure() external override virtual view returns(string memory dataStructure) { return ""; } function getClaimDataStructure() external override virtual view returns(string memory dataStructure) { return ""; } function getPayoutDataStructure() external override virtual view returns(string memory dataStructure) { return ""; } function riskPoolCapacityCallback(uint256 capacity) external override virtual { } }
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.2; import "IComponent.sol"; import "IAccess.sol"; import "IComponentEvents.sol"; import "IRegistry.sol"; import "IComponentOwnerService.sol"; import "IInstanceService.sol"; import "Ownable.sol"; // https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/GUIDELINES.md#style-guidelines abstract contract Component is IComponent, IComponentEvents, Ownable { bytes32 private _componentName; uint256 private _componentId; IComponent.ComponentType private _componentType; IRegistry private _registry; IAccess private _access; IComponentOwnerService private _componentOwnerService; IInstanceService private _instanceService; modifier onlyInstanceOperatorService() { require( _msgSender() == _getContractAddress("InstanceOperatorService"), "ERROR:CMP-001:NOT_INSTANCE_OPERATOR_SERVICE"); _; } modifier onlyComponent() { require( _msgSender() == _getContractAddress("Component"), "ERROR:CMP-002:NOT_COMPONENT"); _; } modifier onlyComponentOwnerService() { require( _msgSender() == address(_componentOwnerService), "ERROR:CMP-003:NOT_COMPONENT_OWNER_SERVICE"); _; } constructor( bytes32 name, IComponent.ComponentType componentType, address registry ) Ownable() { require(registry != address(0), "ERROR:CMP-004:REGISTRY_ADDRESS_ZERO"); _registry = IRegistry(registry); _access = _getAccess(); _componentOwnerService = _getComponentOwnerService(); _instanceService = _getInstanceService(); _componentName = name; _componentType = componentType; emit LogComponentCreated( _componentName, _componentType, address(this), address(_registry)); } function setId(uint256 id) external override onlyComponent { _componentId = id; } function getName() public override view returns(bytes32) { return _componentName; } function getId() public override view returns(uint256) { return _componentId; } function getType() public override view returns(IComponent.ComponentType) { return _componentType; } function getState() public override view returns(IComponent.ComponentState) { return _instanceService.getComponentState(_componentId); } function getOwner() public override view returns(address) { return owner(); } function isProduct() public override view returns(bool) { return _componentType == IComponent.ComponentType.Product; } function isOracle() public override view returns(bool) { return _componentType == IComponent.ComponentType.Oracle; } function isRiskpool() public override view returns(bool) { return _componentType == IComponent.ComponentType.Riskpool; } function getRegistry() external override view returns(IRegistry) { return _registry; } function proposalCallback() public override onlyComponent { _afterPropose(); } function approvalCallback() public override onlyComponent { _afterApprove(); } function declineCallback() public override onlyComponent { _afterDecline(); } function suspendCallback() public override onlyComponent { _afterSuspend(); } function resumeCallback() public override onlyComponent { _afterResume(); } function pauseCallback() public override onlyComponent { _afterPause(); } function unpauseCallback() public override onlyComponent { _afterUnpause(); } function archiveCallback() public override onlyComponent { _afterArchive(); } // these functions are intended to be overwritten to implement // component specific notification handling function _afterPropose() internal virtual {} function _afterApprove() internal virtual {} function _afterDecline() internal virtual {} function _afterSuspend() internal virtual {} function _afterResume() internal virtual {} function _afterPause() internal virtual {} function _afterUnpause() internal virtual {} function _afterArchive() internal virtual {} function _getAccess() internal view returns (IAccess) { return IAccess(_getContractAddress("Access")); } function _getInstanceService() internal view returns (IInstanceService) { return IInstanceService(_getContractAddress("InstanceService")); } function _getComponentOwnerService() internal view returns (IComponentOwnerService) { return IComponentOwnerService(_getContractAddress("ComponentOwnerService")); } function _getContractAddress(bytes32 contractName) internal view returns (address) { return _registry.getContract(contractName); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol) pragma solidity ^0.8.0; import "IERC20.sol"; import "IERC20Metadata.sol"; import "Context.sol"; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC20 * applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20 is Context, IERC20, IERC20Metadata { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * The default value of {decimals} is 18. To select a different value for * {decimals} you should overload it. * * All two of these values are immutable: they can only be set once during * construction. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless this function is * overridden; * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `to` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address to, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _transfer(owner, to, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on * `transferFrom`. This is semantically equivalent to an infinite approval. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _approve(owner, spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * NOTE: Does not update the allowance if the current allowance * is the maximum `uint256`. * * Requirements: * * - `from` and `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. * - the caller must have allowance for ``from``'s tokens of at least * `amount`. */ function transferFrom( address from, address to, uint256 amount ) public virtual override returns (bool) { address spender = _msgSender(); _spendAllowance(from, spender, amount); _transfer(from, to, amount); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { address owner = _msgSender(); _approve(owner, spender, allowance(owner, spender) + addedValue); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { address owner = _msgSender(); uint256 currentAllowance = allowance(owner, spender); require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(owner, spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `from` to `to`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. */ function _transfer( address from, address to, uint256 amount ) internal virtual { require(from != address(0), "ERC20: transfer from the zero address"); require(to != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(from, to, amount); uint256 fromBalance = _balances[from]; require(fromBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[from] = fromBalance - amount; } _balances[to] += amount; emit Transfer(from, to, amount); _afterTokenTransfer(from, to, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; _balances[account] += amount; emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; } _totalSupply -= amount; emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve( address owner, address spender, uint256 amount ) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Updates `owner` s allowance for `spender` based on spent `amount`. * * Does not update the allowance amount in case of infinite allowance. * Revert if not enough allowance is available. * * Might emit an {Approval} event. */ function _spendAllowance( address owner, address spender, uint256 amount ) internal virtual { uint256 currentAllowance = allowance(owner, spender); if (currentAllowance != type(uint256).max) { require(currentAllowance >= amount, "ERC20: insufficient allowance"); unchecked { _approve(owner, spender, currentAllowance - amount); } } } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 amount ) internal virtual {} }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; import "IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.2; interface IQuery { struct OracleRequest { bytes32 processId; uint256 responsibleOracleId; address callbackContractAddress; string callbackMethodName; bytes data; uint256 createdAt; } event LogOracleRequested( bytes32 processId, uint256 requestId, uint256 responsibleOracleId ); event LogOracleResponded( bytes32 processId, uint256 requestId, address responder, bool success ); event LogOracleCanceled( uint256 requestId ); function request( bytes32 processId, bytes calldata input, string calldata callbackMethodName, address callbackContractAddress, uint256 responsibleOracleId ) external returns (uint256 requestId); function respond( uint256 requestId, address responder, bytes calldata data ) external; function cancel(uint256 requestId) external; }
{ "evmVersion": "istanbul", "optimizer": { "enabled": true, "runs": 200 }, "libraries": { "InstanceService.sol": {} }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"inputs":[],"name":"BUNDLE_NAME","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"COMPONENT_NAME","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"COMPONENT_OWNER_SERVICE_NAME","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"INSTANCE_OPERATOR_SERVICE_NAME","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ORACLE_SERVICE_NAME","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"POLICY_NAME","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"POOL_NAME","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRODUCT_SERVICE_NAME","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RISKPOOL_SERVICE_NAME","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TREASURY_NAME","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"riskpoolId","type":"uint256"}],"name":"activeBundles","outputs":[{"internalType":"uint256","name":"numberOfActiveBundles","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bundles","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"processId","type":"bytes32"}],"name":"claims","outputs":[{"internalType":"uint256","name":"numberOfClaims","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"idx","type":"uint256"}],"name":"contractName","outputs":[{"internalType":"bytes32","name":"name","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contracts","outputs":[{"internalType":"uint256","name":"numberOfContracts","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"riskpoolId","type":"uint256"},{"internalType":"uint256","name":"bundleIdx","type":"uint256"}],"name":"getActiveBundleId","outputs":[{"internalType":"uint256","name":"bundleId","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"processId","type":"bytes32"}],"name":"getApplication","outputs":[{"components":[{"internalType":"enum IPolicy.ApplicationState","name":"state","type":"uint8"},{"internalType":"uint256","name":"premiumAmount","type":"uint256"},{"internalType":"uint256","name":"sumInsuredAmount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256","name":"createdAt","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"}],"internalType":"struct IPolicy.Application","name":"application","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"riskpoolId","type":"uint256"}],"name":"getBalance","outputs":[{"internalType":"uint256","name":"balanceAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"bundleId","type":"uint256"}],"name":"getBundle","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"riskpoolId","type":"uint256"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"enum IBundle.BundleState","name":"state","type":"uint8"},{"internalType":"bytes","name":"filter","type":"bytes"},{"internalType":"uint256","name":"capital","type":"uint256"},{"internalType":"uint256","name":"lockedCapital","type":"uint256"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"createdAt","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"}],"internalType":"struct IBundle.Bundle","name":"bundle","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBundleToken","outputs":[{"internalType":"contract IBundleToken","name":"token","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"riskpoolId","type":"uint256"}],"name":"getCapacity","outputs":[{"internalType":"uint256","name":"capacityAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"riskpoolId","type":"uint256"}],"name":"getCapital","outputs":[{"internalType":"uint256","name":"capitalAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getChainId","outputs":[{"internalType":"uint256","name":"chainId","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getChainName","outputs":[{"internalType":"string","name":"chainName","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"processId","type":"bytes32"},{"internalType":"uint256","name":"claimId","type":"uint256"}],"name":"getClaim","outputs":[{"components":[{"internalType":"enum IPolicy.ClaimState","name":"state","type":"uint8"},{"internalType":"uint256","name":"claimAmount","type":"uint256"},{"internalType":"uint256","name":"paidAmount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256","name":"createdAt","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"}],"internalType":"struct IPolicy.Claim","name":"claim","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getComponent","outputs":[{"internalType":"contract IComponent","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"componentAddress","type":"address"}],"name":"getComponentId","outputs":[{"internalType":"uint256","name":"componentId","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getComponentOwnerService","outputs":[{"internalType":"contract IComponentOwnerService","name":"service","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"componentId","type":"uint256"}],"name":"getComponentState","outputs":[{"internalType":"enum IComponent.ComponentState","name":"componentState","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"componentId","type":"uint256"}],"name":"getComponentToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"componentId","type":"uint256"}],"name":"getComponentType","outputs":[{"internalType":"enum IComponent.ComponentType","name":"componentType","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDefaultAdminRole","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFeeFractionFullUnit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFullCollateralizationLevel","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getInstanceId","outputs":[{"internalType":"bytes32","name":"instanceId","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getInstanceOperator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getInstanceOperatorService","outputs":[{"internalType":"contract IInstanceOperatorService","name":"service","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getInstanceWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"riskpoolId","type":"uint256"}],"name":"getMaximumNumberOfActiveBundles","outputs":[{"internalType":"uint256","name":"maximumNumberOfActiveBundles","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"bpKey","type":"bytes32"}],"name":"getMetadata","outputs":[{"components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"productId","type":"uint256"},{"internalType":"enum IPolicy.PolicyFlowState","name":"state","type":"uint8"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256","name":"createdAt","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"}],"internalType":"struct IPolicy.Metadata","name":"metadata","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"idx","type":"uint256"}],"name":"getOracleId","outputs":[{"internalType":"uint256","name":"oracleId","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOracleProviderRole","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOracleService","outputs":[{"internalType":"contract IOracleService","name":"service","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"processId","type":"bytes32"},{"internalType":"uint256","name":"payoutId","type":"uint256"}],"name":"getPayout","outputs":[{"components":[{"internalType":"uint256","name":"claimId","type":"uint256"},{"internalType":"enum IPolicy.PayoutState","name":"state","type":"uint8"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256","name":"createdAt","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"}],"internalType":"struct IPolicy.Payout","name":"payout","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"processId","type":"bytes32"}],"name":"getPolicy","outputs":[{"components":[{"internalType":"enum IPolicy.PolicyState","name":"state","type":"uint8"},{"internalType":"uint256","name":"premiumExpectedAmount","type":"uint256"},{"internalType":"uint256","name":"premiumPaidAmount","type":"uint256"},{"internalType":"uint256","name":"claimsCount","type":"uint256"},{"internalType":"uint256","name":"openClaimsCount","type":"uint256"},{"internalType":"uint256","name":"payoutMaxAmount","type":"uint256"},{"internalType":"uint256","name":"payoutAmount","type":"uint256"},{"internalType":"uint256","name":"createdAt","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"}],"internalType":"struct IPolicy.Policy","name":"policy","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"idx","type":"uint256"}],"name":"getProductId","outputs":[{"internalType":"uint256","name":"productId","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getProductOwnerRole","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getProductService","outputs":[{"internalType":"contract IProductService","name":"service","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRegistry","outputs":[{"internalType":"contract IRegistry","name":"service","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"riskpoolId","type":"uint256"}],"name":"getRiskpool","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"wallet","type":"address"},{"internalType":"address","name":"erc20Token","type":"address"},{"internalType":"uint256","name":"collateralizationLevel","type":"uint256"},{"internalType":"uint256","name":"sumOfSumInsuredCap","type":"uint256"},{"internalType":"uint256","name":"sumOfSumInsuredAtRisk","type":"uint256"},{"internalType":"uint256","name":"capital","type":"uint256"},{"internalType":"uint256","name":"lockedCapital","type":"uint256"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"createdAt","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"}],"internalType":"struct IPool.Pool","name":"riskPool","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"idx","type":"uint256"}],"name":"getRiskpoolId","outputs":[{"internalType":"uint256","name":"riskpoolId","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRiskpoolKeeperRole","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRiskpoolService","outputs":[{"internalType":"contract IRiskpoolService","name":"service","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"riskpoolId","type":"uint256"}],"name":"getRiskpoolWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getStakedAssets","outputs":[{"internalType":"bytes","name":"data","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getStakingRequirements","outputs":[{"internalType":"bytes","name":"data","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"riskpoolId","type":"uint256"}],"name":"getTotalValueLocked","outputs":[{"internalType":"uint256","name":"totalValueLockedAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTreasuryAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"principal","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"registry","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"oracles","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"processId","type":"bytes32"}],"name":"payouts","outputs":[{"internalType":"uint256","name":"numberOfPayouts","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"processIds","outputs":[{"internalType":"uint256","name":"numberOfProcessIds","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"products","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"riskpools","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"riskpoolId","type":"uint256"}],"name":"unburntBundles","outputs":[{"internalType":"uint256","name":"numberOfUnburntBundles","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b506200001c62000022565b620000e4565b600054610100900460ff16156200008f5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff9081161015620000e2576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b612ebd80620000f46000396000f3fe608060405234801561001057600080fd5b50600436106103e65760003560e01c80637f22c2d91161020a578063c4d66de811610125578063e543ecb9116100b8578063ec833b0c11610087578063ec833b0c14610894578063eff0f592146108a7578063f1d354d0146108ba578063f6b3e7d0146108c2578063ff3f3883146108d5576103e6565b8063e543ecb91461083b578063e882892214610854578063eb35783c1461086c578063eb80211414610874576103e6565b8063d49d21c0116100f4578063d49d21c0146107fa578063d722b0bc14610802578063dd51c86a1461080a578063e00246041461082a576103e6565b8063c4d66de8146107aa578063c559783e146107bf578063c71e261f146107d2578063cef58f13146107da576103e6565b8063a44330c41161019d578063ab9c6ee41161016c578063ab9c6ee41461075e578063aeddb90514610771578063bc506f6414610784578063bcd5349f14610797576103e6565b8063a44330c41461071b578063a5961b4c14610723578063a5c0f5a114610743578063a7ecda3614610756576103e6565b8063a3f66bd2116101d9578063a3f66bd2146106bf578063a3f685f9146106e0578063a4266a6614610700578063a427056e14610713576103e6565b80637f22c2d91461066157806391d14854146106815780639f77a605146106a4578063a054381f146106b7576103e6565b80633ffdd2f31161030557806352b5b0ef116102985780636319112b116102675780636319112b1461062e5780636c0f79b6146106365780636fa298531461063e578063775a4048146106465780637db328441461064e576103e6565b806352b5b0ef146105c75780635ab1bd53146105e65780635e6877be146105fe5780635e966e451461060e576103e6565b80634f27da18116102d45780634f27da181461058757806350e1a19b1461059a57806351b2fb90146105ac57806352a9c8d7146105bf576103e6565b80633ffdd2f31461055c5780634288121d14610564578063442ed8171461056c5780634908163714610574576103e6565b80632898312f1161037d5780633408e4701161034c5780633408e4701461051b57806339c6fa90146105215780633a42b053146105295780633f5d923514610549576103e6565b80632898312f146104be57806329560980146104d55780632b1c7f73146104e85780632d0821b7146104fb576103e6565b806318442e63116103b957806318442e631461048b57806318ff21c3146104935780631e010439146104a35780632857373a146104b6576103e6565b8063038696bb146103eb578063091924dc1461041b5780630c131757146104235780631551100f1461043f575b600080fd5b6103fe6103f93660046125e1565b6108e8565b6040516001600160a01b0390911681526020015b60405180910390f35b6103fe61096e565b61043163141bdbdb60e21b81565b604051908152602001610412565b61043160008054604080514660208201526201000090920460601b6bffffffffffffffffffffffff19169082015260540160405160208183030381529060405280519060200120905090565b610431610998565b61043165506f6c69637960d01b81565b6104316104b13660046125e1565b610a15565b610431610a9e565b6104316c4f7261636c655365727669636560981b81565b6104316104e33660046125e1565b610ae3565b6104316104f6366004612589565b610b6b565b61050e6105093660046125e1565b610bea565b6040516104129190612b14565b46610431565b6103fe610c72565b61053c6105373660046125e1565b610d11565b6040516104129190612a75565b6104316105573660046125e1565b610d6c565b610431610df4565b6103fe610e39565b6103fe610e55565b6103fe6105823660046125e1565b610e72565b6103fe6105953660046125e1565b610ea4565b61043167547265617375727960c01b81565b6104316810dbdb5c1bdb995b9d60ba1b81565b610431610ed6565b61043174436f6d706f6e656e744f776e65725365727669636560581b81565b6103fe6000546201000090046001600160a01b031690565b6104316542756e646c6560d01b81565b61062161061c3660046125e1565b610f1b565b6040516104129190612a88565b610431610f98565b610431610fdd565b6103fe61102c565b61043161104f565b61043161065c3660046125e1565b611094565b61067461066f366004612640565b6110c6565b6040516104129190612aaf565b61069461068f366004612611565b61118c565b6040519015158152602001610412565b6104316106b23660046125e1565b611211565b610431611243565b61043176496e7374616e63654f70657261746f725365727669636560481b81565b6106f36106ee3660046125e1565b611288565b6040516104129190612c44565b61043161070e3660046125e1565b611353565b610431611385565b6103fe6113d5565b6107366107313660046125e1565b611452565b6040516104129190612bab565b6104316107513660046125e1565b611509565b6103fe61153b565b61053c61076c3660046125e1565b611556565b61043161077f3660046125e1565b6115ac565b6106746107923660046125e1565b6115e0565b6104316107a53660046125e1565b611698565b6107bd6107b8366004612589565b611730565b005b6104316107cd3660046125e1565b6118ae565b6104316118e0565b6107ed6107e8366004612640565b611925565b6040516104129190612bf8565b6104316119e4565b61053c611a29565b61081d6108183660046125e1565b611aca565b6040516104129190612aa2565b6006546001600160a01b03166103fe565b6104316e5269736b706f6f6c5365727669636560881b81565b6104316d50726f647563745365727669636560901b81565b6103fe611b47565b6108876108823660046125e1565b611bd6565b6040516104129190612cb1565b6104316108a2366004612640565b611cc2565b6104316108b53660046125e1565b611d46565b610431611d7a565b6104316108d03660046125e1565b611dbf565b6104316108e33660046125e1565b611df6565b60065460405163038696bb60e01b8152600481018390526000916001600160a01b03169063038696bb906024015b60206040518083038186803b15801561092e57600080fd5b505afa158015610942573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061096691906125a5565b90505b919050565b600061099376496e7374616e63654f70657261746f725365727669636560481b611e2b565b905090565b600254604080516318442e6360e01b815290516000926001600160a01b0316916318442e63916004808301926020929190829003018186803b1580156109dd57600080fd5b505afa1580156109f1573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061099391906125f9565b600554604051633ae0084560e21b8152600481018390526000916001600160a01b03169063eb802114906024016101606040518083038186803b158015610a5b57600080fd5b505afa158015610a6f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a939190612998565b610100015192915050565b6003546040805163142b9b9d60e11b815290516000926001600160a01b031691632857373a916004808301926020929190829003018186803b1580156109dd57600080fd5b600554604051633ae0084560e21b8152600481018390526000916001600160a01b03169063eb802114906024016101606040518083038186803b158015610b2957600080fd5b505afa158015610b3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b619190612998565b60c0015192915050565b600354604051632b1c7f7360e01b81526001600160a01b0383811660048301526000921690632b1c7f73906024015b60206040518083038186803b158015610bb257600080fd5b505afa158015610bc6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061096691906125f9565b610bf26123f3565b600254604051632d0821b760e01b8152600481018490526001600160a01b0390911690632d0821b79060240160006040518083038186803b158015610c3657600080fd5b505afa158015610c4a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526109669190810190612747565b600080610c9876496e7374616e63654f70657261746f725365727669636560481b611e2b565b9050806001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b158015610cd357600080fd5b505afa158015610ce7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d0b91906125a5565b91505090565b60405162461bcd60e51b815260206004820152602260248201527f4552524f523a49532d3030323a494d504c454d454e4154494f4e5f4d495353496044820152614e4760f01b60648201526060906084015b60405180910390fd5b600554604051633ae0084560e21b8152600481018390526000916001600160a01b03169063eb802114906024016101606040518083038186803b158015610db257600080fd5b505afa158015610dc6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dea9190612998565b60e0015192915050565b60015460408051633ffdd2f360e01b815290516000926001600160a01b031691633ffdd2f3916004808301926020929190829003018186803b1580156109dd57600080fd5b60006109936d50726f647563745365727669636560901b611e2b565b60006109936e5269736b706f6f6c5365727669636560881b611e2b565b600654604051634908163760e01b8152600481018390526000916001600160a01b031690634908163790602401610916565b6003546040516309e4fb4360e31b8152600481018390526000916001600160a01b031690634f27da1890602401610916565b600154604080516352a9c8d760e01b815290516000926001600160a01b0316916352a9c8d7916004808301926020929190829003018186803b1580156109dd57600080fd5b600354604051635e966e4560e01b8152600481018390526000916001600160a01b031690635e966e459060240160206040518083038186803b158015610f6057600080fd5b505afa158015610f74573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109669190612661565b60065460408051634667ae5160e11b815290516000926001600160a01b031691638ccf5ca2916004808301926020929190829003018186803b1580156109dd57600080fd5b60008060029054906101000a90046001600160a01b03166001600160a01b0316636c0f79b66040518163ffffffff1660e01b815260040160206040518083038186803b1580156109dd57600080fd5b600061099374436f6d706f6e656e744f776e65725365727669636560581b611e2b565b60015460408051630eeb480960e31b815290516000926001600160a01b03169163775a4048916004808301926020929190829003018186803b1580156109dd57600080fd5b600554604051631f6cca1160e21b8152600481018390526000916001600160a01b031690637db3284490602401610b9a565b6111006040805160c08101909152806000815260200160008152602001600081526020016060815260200160008152602001600081525090565b60048054604051637f22c2d960e01b8152918201859052602482018490526001600160a01b031690637f22c2d99060440160006040518083038186803b15801561114957600080fd5b505afa15801561115d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611185919081019061269c565b9392505050565b600154604051632474521560e21b8152600481018490526001600160a01b03838116602483015260009216906391d148549060440160206040518083038186803b1580156111d957600080fd5b505afa1580156111ed573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061118591906125c1565b600354604051639f77a60560e01b8152600481018390526000916001600160a01b031690639f77a60590602401610b9a565b6003546040805163a054381f60e01b815290516000926001600160a01b03169163a054381f916004808301926020929190829003018186803b1580156109dd57600080fd5b6112d8604080516101208101909152806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6004805460405163a3f685f960e01b81529182018490526001600160a01b03169063a3f685f9906024016101206040518083038186803b15801561131b57600080fd5b505afa15801561132f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109669190612913565b600554604051635213353360e11b8152600481018390526000916001600160a01b03169063a4266a6690602401610b9a565b6000600460009054906101000a90046001600160a01b03166001600160a01b031663a427056e6040518163ffffffff1660e01b815260040160206040518083038186803b1580156109dd57600080fd5b60065460408051632910cc3160e21b815290516000926001600160a01b03169163a44330c4916004808301926020929190829003018186803b15801561141a57600080fd5b505afa15801561142e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061099391906125a5565b61148b6040805160c081018252600080825260208201819052909182019081526020016060815260200160008152602001600081525090565b6004805460405163296586d360e21b81529182018490526001600160a01b03169063a5961b4c9060240160006040518083038186803b1580156114cd57600080fd5b505afa1580156114e1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610966919081019061281b565b60035460405163a5c0f5a160e01b8152600481018390526000916001600160a01b03169063a5c0f5a190602401610b9a565b60006109936c4f7261636c655365727669636560981b611e2b565b60405162461bcd60e51b815260206004820152602260248201527f4552524f523a49532d3030313a494d504c454d454e4154494f4e5f4d495353496044820152614e4760f01b6064820152606090608401610d63565b6004805460405163be183b1160e01b81529182018390526000916001600160a01b039091169063be183b1190602401610b9a565b61161a6040805160c08101909152806000815260200160008152602001600081526020016060815260200160008152602001600081525090565b60048054604051632f141bd960e21b81529182018490526001600160a01b03169063bc506f649060240160006040518083038186803b15801561165c57600080fd5b505afa158015611670573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610966919081019061269c565b600554604051633ae0084560e21b81526004810183905260009182916001600160a01b039091169063eb802114906024016101606040518083038186803b1580156116e257600080fd5b505afa1580156116f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061171a9190612998565b90508060e001518160c001516111859190612d7e565b600054610100900460ff16158080156117505750600054600160ff909116105b8061176a5750303b15801561176a575060005460ff166001145b6117cd5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610d63565b6000805460ff1916600117905580156117f0576000805461ff0019166101001790555b6000805462010000600160b01b031916620100006001600160a01b0385160217905561181a600090565b6541636365737360d01b1461185c5761183b6541636365737360d01b611e2b565b600180546001600160a01b0319166001600160a01b03929092169190911790555b611864611f13565b80156118aa576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6002546040516362acbc1f60e11b8152600481018390526000916001600160a01b03169063c559783e90602401610b9a565b6003546040805163c71e261f60e01b815290516000926001600160a01b03169163c71e261f916004808301926020929190829003018186803b1580156109dd57600080fd5b61195f6040805160c08101909152600080825260208201908152602001600081526020016060815260200160008152602001600081525090565b6004805460405163cef58f1360e01b8152918201859052602482018490526001600160a01b03169063cef58f139060440160006040518083038186803b1580156119a857600080fd5b505afa1580156119bc573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526111859190810190612899565b60015460408051630352748760e61b815290516000926001600160a01b03169163d49d21c0916004808301926020929190829003018186803b1580156109dd57600080fd5b466000908152600760205260409020805460609190611a4790612dd1565b80601f0160208091040260200160405190810160405280929190818152602001828054611a7390612dd1565b8015611ac05780601f10611a9557610100808354040283529160200191611ac0565b820191906000526020600020905b815481529060010190602001808311611aa357829003601f168201915b5050505050905090565b600354604051636ea8e43560e11b8152600481018390526000916001600160a01b03169063dd51c86a9060240160206040518083038186803b158015611b0f57600080fd5b505afa158015611b23573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109669190612680565b600080600260009054906101000a90046001600160a01b03166001600160a01b03166321df0da76040518163ffffffff1660e01b815260040160206040518083038186803b158015611b9857600080fd5b505afa158015611bac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bd091906125a5565b92915050565b611c456040518061016001604052806000815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b600554604051633ae0084560e21b8152600481018490526001600160a01b039091169063eb802114906024016101606040518083038186803b158015611c8a57600080fd5b505afa158015611c9e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109669190612998565b600554604051633b20cec360e21b815260048101849052602481018390526000916001600160a01b03169063ec833b0c9060440160206040518083038186803b158015611d0e57600080fd5b505afa158015611d22573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061118591906125f9565b6004805460405163163c4b3160e31b81529182018390526000916001600160a01b039091169063b1e2598890602401610b9a565b60055460408051630f1d354d60e41b815290516000926001600160a01b03169163f1d354d0916004808301926020929190829003018186803b1580156109dd57600080fd5b60008054604051630f6b3e7d60e41b815260048101849052620100009091046001600160a01b03169063f6b3e7d090602401610b9a565b600354604051600162c0c77d60e01b03198152600481018390526000916001600160a01b03169063ff3f388390602401610b9a565b60008054604051631c2d8fb360e31b815260048101849052620100009091046001600160a01b03169063e16c7d989060240160206040518083038186803b158015611e7557600080fd5b505afa158015611e89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ead91906125a5565b90506001600160a01b0381166109695760405162461bcd60e51b815260206004820152602560248201527f4552524f523a4352432d3030343a434f4e54524143545f4e4f545f5245474953604482015264151154915160da1b6064820152608401610d63565b600054610100900460ff16611f7e5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610d63565b611f906542756e646c6560d01b611e2b565b600280546001600160a01b0319166001600160a01b0392909216919091179055611fc56810dbdb5c1bdb995b9d60ba1b611e2b565b600380546001600160a01b0319166001600160a01b0392909216919091179055611ff765506f6c69637960d01b611e2b565b600480546001600160a01b0319166001600160a01b039290921691909117905561202763141bdbdb60e21b611e2b565b600580546001600160a01b0319166001600160a01b039290921691909117905561205b67547265617375727960c01b611e2b565b600680546001600160a01b0319166001600160a01b0392909216919091179055612083612085565b565b60408051808201909152601481527308ae8d0cae4caeada409ac2d2dcdccae85e8aa8960631b602080830191825260016000526007905290516120e9917fb39221ace053465ec3453ce2b36430bd138b997ecea25c1043da0c366812b82891612465565b5060408051808201909152600a81526908edecae4d8d25e8aa8960b31b60208083019182526005600052600790529051612144917fbcdda56b5d08466ec462cbbe0adfa57cb0a15fcc8940ef68f702f21b787bc93591612465565b506040805180820190915260078082526647616e6163686560c81b602080840191825261053960005291909152905161219e917f96a76633116ac3161b66b4be70f114c9a245f4bbf414dc7a4d0edce8c01734cf91612465565b5060408051808201909152600b81526a476e6f7369732f7844616960a81b602080830191825260646000526007905290516121fa917f06179e496907eb3333fef2ed2194553681badbb6d717316349bf33d21ec47e1291612465565b5060408051808201909152600a815269536f6b6f6c2f53504f4160b01b6020808301918252604d600052600790529051612255917f58f3d94c4a880e721e755344405d3fe6076875bf5b3ad388d0a326a85bcabfb591612465565b50604080518082019091526015815274506f6c79676f6e204d61696e6e65742f4d4154494360581b602080830191825260896000526007905290516122bb917f65420a8d28339aeca441a0c94a464f6387b468f3f5ea5c247a6df59a5f7b886691612465565b5060408051808201909152600c81526b4d756d6261692f4d4154494360a01b6020808301918252611f41600052600790529051612319917f4d67172c71df6b75e948764b65521db84c0c61e94d5f3739b666417e9471e58491612465565b50604080518082019091526016815275082ecc2d8c2dcc6d0ca40865a86d0c2d2dc5e82ac82b60531b602080830191825261a86a600052600790529051612381917fa4356065248d86930c73e944e85f9d029fb0f52c0b8312d1a61bfbc9797ef51491612465565b5060408051808201909152601b81527f4176616c616e6368652046756a6920546573746e65742f415641580000000000602080830191825261a8696000526007905290516123f0917f57a00da22bfc0a372532b5dfacb7ddf387626f66de87422d191e09ea7493495691612465565b50565b6040518061014001604052806000815260200160008152602001600081526020016000600381111561243557634e487b7160e01b600052602160045260246000fd5b81526020016060815260200160008152602001600081526020016000815260200160008152602001600081525090565b82805461247190612dd1565b90600052602060002090601f01602090048101928261249357600085556124d9565b82601f106124ac57805160ff19168380011785556124d9565b828001600101855582156124d9579182015b828111156124d95782518255916020019190600101906124be565b506124e59291506124e9565b5090565b5b808211156124e557600081556001016124ea565b805161096981612e58565b600082601f830112612519578081fd5b815167ffffffffffffffff81111561253357612533612e22565b612546601f8201601f1916602001612d4d565b81815284602083860101111561255a578283fd5b61256b826020830160208701612da1565b949350505050565b805161096981612e6d565b805161096981612e7a565b60006020828403121561259a578081fd5b813561118581612e58565b6000602082840312156125b6578081fd5b815161118581612e58565b6000602082840312156125d2578081fd5b81518015158114611185578182fd5b6000602082840312156125f2578081fd5b5035919050565b60006020828403121561260a578081fd5b5051919050565b60008060408385031215612623578081fd5b82359150602083013561263581612e58565b809150509250929050565b60008060408385031215612652578182fd5b50508035926020909101359150565b600060208284031215612672578081fd5b815160078110611185578182fd5b600060208284031215612691578081fd5b815161118581612e7a565b6000602082840312156126ad578081fd5b815167ffffffffffffffff808211156126c4578283fd5b9083019060c082860312156126d7578283fd5b6126e160c0612d4d565b82516126ec81612e6d565b808252506020830151602082015260408301516040820152606083015182811115612715578485fd5b61272187828601612509565b6060830152506080830151608082015260a083015160a082015280935050505092915050565b600060208284031215612758578081fd5b815167ffffffffffffffff8082111561276f578283fd5b8184019150610140808387031215612785578384fd5b61278e81612d4d565b90508251815260208301516020820152604083015160408201526127b460608401612573565b60608201526080830151828111156127ca578485fd5b6127d687828601612509565b60808301525060a0838101519082015260c0808401519082015260e0808401519082015261010080840151908201526101209283015192810192909252509392505050565b60006020828403121561282c578081fd5b815167ffffffffffffffff80821115612843578283fd5b9083019060c08286031215612856578283fd5b61286060c0612d4d565b825161286b81612e58565b8152602083810151908201526128836040840161257e565b6040820152606083015182811115612715578485fd5b6000602082840312156128aa578081fd5b815167ffffffffffffffff808211156128c1578283fd5b9083019060c082860312156128d4578283fd5b6128de60c0612d4d565b825181526020830151600281106128f3578485fd5b602082015260408381015190820152606083015182811115612715578485fd5b6000610120808385031215612926578182fd5b61292f81612d4d565b905061293a8361257e565b81526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015160e08201526101008084015181830152508091505092915050565b60006101608083850312156129ab578182fd5b6129b481612d4d565b9050825181526129c6602084016124fe565b60208201526129d7604084016124fe565b6040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015160e08201526101008084015181830152506101208084015181830152506101408084015181830152508091505092915050565b60008151808452612a54816020860160208601612da1565b601f01601f19169290920160200192915050565b612a7181612e38565b9052565b6000602082526111856020830184612a3c565b6020810160078310612a9c57612a9c612e0c565b91905290565b60208101612a9c83612e48565b6000602082528251612ac081612e38565b806020840152506020830151604083015260408301516060830152606083015160c06080840152612af460e0840182612a3c565b9050608084015160a084015260a084015160c08401528091505092915050565b6000602082528251602083015260208301516040830152604083015160608301526060830151612b476080840182612a68565b5060808301516101408060a0850152612b64610160850183612a3c565b915060a085015160c085015260c085015160e085015260e0850151610100818187015280870151915050610120818187015280870151838701525050508091505092915050565b60006020825260018060a01b038351166020830152602083015160408301526040830151612bd881612e48565b80606084015250606083015160c06080840152612af460e0840182612a3c565b60006020825282516020830152602083015160028110612c1a57612c1a612e0c565b8060408401525060408301516060830152606083015160c06080840152612af460e0840182612a3c565b8151610120820190612c5581612e48565b808352506020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e083015160e083015261010080840151818401525092915050565b81518152602080830151610160830191612cd5908401826001600160a01b03169052565b506040830151612cf060408401826001600160a01b03169052565b50606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e083015160e083015261010080840151818401525061012080840151818401525061014080840151818401525092915050565b604051601f8201601f1916810167ffffffffffffffff81118282101715612d7657612d76612e22565b604052919050565b600082821015612d9c57634e487b7160e01b81526011600452602481fd5b500390565b60005b83811015612dbc578181015183820152602001612da4565b83811115612dcb576000848401525b50505050565b600281046001821680612de557607f821691505b60208210811415612e0657634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b600481106123f0576123f0612e0c565b600381106123f0576123f0612e0c565b6001600160a01b03811681146123f057600080fd5b600481106123f057600080fd5b600381106123f057600080fdfea26469706673582212204e1660b0e27116d5ed491a1c24d0670440ed1a3122fbb29c776b62b119d4843264736f6c63430008020033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106103e65760003560e01c80637f22c2d91161020a578063c4d66de811610125578063e543ecb9116100b8578063ec833b0c11610087578063ec833b0c14610894578063eff0f592146108a7578063f1d354d0146108ba578063f6b3e7d0146108c2578063ff3f3883146108d5576103e6565b8063e543ecb91461083b578063e882892214610854578063eb35783c1461086c578063eb80211414610874576103e6565b8063d49d21c0116100f4578063d49d21c0146107fa578063d722b0bc14610802578063dd51c86a1461080a578063e00246041461082a576103e6565b8063c4d66de8146107aa578063c559783e146107bf578063c71e261f146107d2578063cef58f13146107da576103e6565b8063a44330c41161019d578063ab9c6ee41161016c578063ab9c6ee41461075e578063aeddb90514610771578063bc506f6414610784578063bcd5349f14610797576103e6565b8063a44330c41461071b578063a5961b4c14610723578063a5c0f5a114610743578063a7ecda3614610756576103e6565b8063a3f66bd2116101d9578063a3f66bd2146106bf578063a3f685f9146106e0578063a4266a6614610700578063a427056e14610713576103e6565b80637f22c2d91461066157806391d14854146106815780639f77a605146106a4578063a054381f146106b7576103e6565b80633ffdd2f31161030557806352b5b0ef116102985780636319112b116102675780636319112b1461062e5780636c0f79b6146106365780636fa298531461063e578063775a4048146106465780637db328441461064e576103e6565b806352b5b0ef146105c75780635ab1bd53146105e65780635e6877be146105fe5780635e966e451461060e576103e6565b80634f27da18116102d45780634f27da181461058757806350e1a19b1461059a57806351b2fb90146105ac57806352a9c8d7146105bf576103e6565b80633ffdd2f31461055c5780634288121d14610564578063442ed8171461056c5780634908163714610574576103e6565b80632898312f1161037d5780633408e4701161034c5780633408e4701461051b57806339c6fa90146105215780633a42b053146105295780633f5d923514610549576103e6565b80632898312f146104be57806329560980146104d55780632b1c7f73146104e85780632d0821b7146104fb576103e6565b806318442e63116103b957806318442e631461048b57806318ff21c3146104935780631e010439146104a35780632857373a146104b6576103e6565b8063038696bb146103eb578063091924dc1461041b5780630c131757146104235780631551100f1461043f575b600080fd5b6103fe6103f93660046125e1565b6108e8565b6040516001600160a01b0390911681526020015b60405180910390f35b6103fe61096e565b61043163141bdbdb60e21b81565b604051908152602001610412565b61043160008054604080514660208201526201000090920460601b6bffffffffffffffffffffffff19169082015260540160405160208183030381529060405280519060200120905090565b610431610998565b61043165506f6c69637960d01b81565b6104316104b13660046125e1565b610a15565b610431610a9e565b6104316c4f7261636c655365727669636560981b81565b6104316104e33660046125e1565b610ae3565b6104316104f6366004612589565b610b6b565b61050e6105093660046125e1565b610bea565b6040516104129190612b14565b46610431565b6103fe610c72565b61053c6105373660046125e1565b610d11565b6040516104129190612a75565b6104316105573660046125e1565b610d6c565b610431610df4565b6103fe610e39565b6103fe610e55565b6103fe6105823660046125e1565b610e72565b6103fe6105953660046125e1565b610ea4565b61043167547265617375727960c01b81565b6104316810dbdb5c1bdb995b9d60ba1b81565b610431610ed6565b61043174436f6d706f6e656e744f776e65725365727669636560581b81565b6103fe6000546201000090046001600160a01b031690565b6104316542756e646c6560d01b81565b61062161061c3660046125e1565b610f1b565b6040516104129190612a88565b610431610f98565b610431610fdd565b6103fe61102c565b61043161104f565b61043161065c3660046125e1565b611094565b61067461066f366004612640565b6110c6565b6040516104129190612aaf565b61069461068f366004612611565b61118c565b6040519015158152602001610412565b6104316106b23660046125e1565b611211565b610431611243565b61043176496e7374616e63654f70657261746f725365727669636560481b81565b6106f36106ee3660046125e1565b611288565b6040516104129190612c44565b61043161070e3660046125e1565b611353565b610431611385565b6103fe6113d5565b6107366107313660046125e1565b611452565b6040516104129190612bab565b6104316107513660046125e1565b611509565b6103fe61153b565b61053c61076c3660046125e1565b611556565b61043161077f3660046125e1565b6115ac565b6106746107923660046125e1565b6115e0565b6104316107a53660046125e1565b611698565b6107bd6107b8366004612589565b611730565b005b6104316107cd3660046125e1565b6118ae565b6104316118e0565b6107ed6107e8366004612640565b611925565b6040516104129190612bf8565b6104316119e4565b61053c611a29565b61081d6108183660046125e1565b611aca565b6040516104129190612aa2565b6006546001600160a01b03166103fe565b6104316e5269736b706f6f6c5365727669636560881b81565b6104316d50726f647563745365727669636560901b81565b6103fe611b47565b6108876108823660046125e1565b611bd6565b6040516104129190612cb1565b6104316108a2366004612640565b611cc2565b6104316108b53660046125e1565b611d46565b610431611d7a565b6104316108d03660046125e1565b611dbf565b6104316108e33660046125e1565b611df6565b60065460405163038696bb60e01b8152600481018390526000916001600160a01b03169063038696bb906024015b60206040518083038186803b15801561092e57600080fd5b505afa158015610942573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061096691906125a5565b90505b919050565b600061099376496e7374616e63654f70657261746f725365727669636560481b611e2b565b905090565b600254604080516318442e6360e01b815290516000926001600160a01b0316916318442e63916004808301926020929190829003018186803b1580156109dd57600080fd5b505afa1580156109f1573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061099391906125f9565b600554604051633ae0084560e21b8152600481018390526000916001600160a01b03169063eb802114906024016101606040518083038186803b158015610a5b57600080fd5b505afa158015610a6f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a939190612998565b610100015192915050565b6003546040805163142b9b9d60e11b815290516000926001600160a01b031691632857373a916004808301926020929190829003018186803b1580156109dd57600080fd5b600554604051633ae0084560e21b8152600481018390526000916001600160a01b03169063eb802114906024016101606040518083038186803b158015610b2957600080fd5b505afa158015610b3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b619190612998565b60c0015192915050565b600354604051632b1c7f7360e01b81526001600160a01b0383811660048301526000921690632b1c7f73906024015b60206040518083038186803b158015610bb257600080fd5b505afa158015610bc6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061096691906125f9565b610bf26123f3565b600254604051632d0821b760e01b8152600481018490526001600160a01b0390911690632d0821b79060240160006040518083038186803b158015610c3657600080fd5b505afa158015610c4a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526109669190810190612747565b600080610c9876496e7374616e63654f70657261746f725365727669636560481b611e2b565b9050806001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b158015610cd357600080fd5b505afa158015610ce7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d0b91906125a5565b91505090565b60405162461bcd60e51b815260206004820152602260248201527f4552524f523a49532d3030323a494d504c454d454e4154494f4e5f4d495353496044820152614e4760f01b60648201526060906084015b60405180910390fd5b600554604051633ae0084560e21b8152600481018390526000916001600160a01b03169063eb802114906024016101606040518083038186803b158015610db257600080fd5b505afa158015610dc6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dea9190612998565b60e0015192915050565b60015460408051633ffdd2f360e01b815290516000926001600160a01b031691633ffdd2f3916004808301926020929190829003018186803b1580156109dd57600080fd5b60006109936d50726f647563745365727669636560901b611e2b565b60006109936e5269736b706f6f6c5365727669636560881b611e2b565b600654604051634908163760e01b8152600481018390526000916001600160a01b031690634908163790602401610916565b6003546040516309e4fb4360e31b8152600481018390526000916001600160a01b031690634f27da1890602401610916565b600154604080516352a9c8d760e01b815290516000926001600160a01b0316916352a9c8d7916004808301926020929190829003018186803b1580156109dd57600080fd5b600354604051635e966e4560e01b8152600481018390526000916001600160a01b031690635e966e459060240160206040518083038186803b158015610f6057600080fd5b505afa158015610f74573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109669190612661565b60065460408051634667ae5160e11b815290516000926001600160a01b031691638ccf5ca2916004808301926020929190829003018186803b1580156109dd57600080fd5b60008060029054906101000a90046001600160a01b03166001600160a01b0316636c0f79b66040518163ffffffff1660e01b815260040160206040518083038186803b1580156109dd57600080fd5b600061099374436f6d706f6e656e744f776e65725365727669636560581b611e2b565b60015460408051630eeb480960e31b815290516000926001600160a01b03169163775a4048916004808301926020929190829003018186803b1580156109dd57600080fd5b600554604051631f6cca1160e21b8152600481018390526000916001600160a01b031690637db3284490602401610b9a565b6111006040805160c08101909152806000815260200160008152602001600081526020016060815260200160008152602001600081525090565b60048054604051637f22c2d960e01b8152918201859052602482018490526001600160a01b031690637f22c2d99060440160006040518083038186803b15801561114957600080fd5b505afa15801561115d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611185919081019061269c565b9392505050565b600154604051632474521560e21b8152600481018490526001600160a01b03838116602483015260009216906391d148549060440160206040518083038186803b1580156111d957600080fd5b505afa1580156111ed573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061118591906125c1565b600354604051639f77a60560e01b8152600481018390526000916001600160a01b031690639f77a60590602401610b9a565b6003546040805163a054381f60e01b815290516000926001600160a01b03169163a054381f916004808301926020929190829003018186803b1580156109dd57600080fd5b6112d8604080516101208101909152806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6004805460405163a3f685f960e01b81529182018490526001600160a01b03169063a3f685f9906024016101206040518083038186803b15801561131b57600080fd5b505afa15801561132f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109669190612913565b600554604051635213353360e11b8152600481018390526000916001600160a01b03169063a4266a6690602401610b9a565b6000600460009054906101000a90046001600160a01b03166001600160a01b031663a427056e6040518163ffffffff1660e01b815260040160206040518083038186803b1580156109dd57600080fd5b60065460408051632910cc3160e21b815290516000926001600160a01b03169163a44330c4916004808301926020929190829003018186803b15801561141a57600080fd5b505afa15801561142e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061099391906125a5565b61148b6040805160c081018252600080825260208201819052909182019081526020016060815260200160008152602001600081525090565b6004805460405163296586d360e21b81529182018490526001600160a01b03169063a5961b4c9060240160006040518083038186803b1580156114cd57600080fd5b505afa1580156114e1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610966919081019061281b565b60035460405163a5c0f5a160e01b8152600481018390526000916001600160a01b03169063a5c0f5a190602401610b9a565b60006109936c4f7261636c655365727669636560981b611e2b565b60405162461bcd60e51b815260206004820152602260248201527f4552524f523a49532d3030313a494d504c454d454e4154494f4e5f4d495353496044820152614e4760f01b6064820152606090608401610d63565b6004805460405163be183b1160e01b81529182018390526000916001600160a01b039091169063be183b1190602401610b9a565b61161a6040805160c08101909152806000815260200160008152602001600081526020016060815260200160008152602001600081525090565b60048054604051632f141bd960e21b81529182018490526001600160a01b03169063bc506f649060240160006040518083038186803b15801561165c57600080fd5b505afa158015611670573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610966919081019061269c565b600554604051633ae0084560e21b81526004810183905260009182916001600160a01b039091169063eb802114906024016101606040518083038186803b1580156116e257600080fd5b505afa1580156116f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061171a9190612998565b90508060e001518160c001516111859190612d7e565b600054610100900460ff16158080156117505750600054600160ff909116105b8061176a5750303b15801561176a575060005460ff166001145b6117cd5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610d63565b6000805460ff1916600117905580156117f0576000805461ff0019166101001790555b6000805462010000600160b01b031916620100006001600160a01b0385160217905561181a600090565b6541636365737360d01b1461185c5761183b6541636365737360d01b611e2b565b600180546001600160a01b0319166001600160a01b03929092169190911790555b611864611f13565b80156118aa576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6002546040516362acbc1f60e11b8152600481018390526000916001600160a01b03169063c559783e90602401610b9a565b6003546040805163c71e261f60e01b815290516000926001600160a01b03169163c71e261f916004808301926020929190829003018186803b1580156109dd57600080fd5b61195f6040805160c08101909152600080825260208201908152602001600081526020016060815260200160008152602001600081525090565b6004805460405163cef58f1360e01b8152918201859052602482018490526001600160a01b03169063cef58f139060440160006040518083038186803b1580156119a857600080fd5b505afa1580156119bc573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526111859190810190612899565b60015460408051630352748760e61b815290516000926001600160a01b03169163d49d21c0916004808301926020929190829003018186803b1580156109dd57600080fd5b466000908152600760205260409020805460609190611a4790612dd1565b80601f0160208091040260200160405190810160405280929190818152602001828054611a7390612dd1565b8015611ac05780601f10611a9557610100808354040283529160200191611ac0565b820191906000526020600020905b815481529060010190602001808311611aa357829003601f168201915b5050505050905090565b600354604051636ea8e43560e11b8152600481018390526000916001600160a01b03169063dd51c86a9060240160206040518083038186803b158015611b0f57600080fd5b505afa158015611b23573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109669190612680565b600080600260009054906101000a90046001600160a01b03166001600160a01b03166321df0da76040518163ffffffff1660e01b815260040160206040518083038186803b158015611b9857600080fd5b505afa158015611bac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bd091906125a5565b92915050565b611c456040518061016001604052806000815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b600554604051633ae0084560e21b8152600481018490526001600160a01b039091169063eb802114906024016101606040518083038186803b158015611c8a57600080fd5b505afa158015611c9e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109669190612998565b600554604051633b20cec360e21b815260048101849052602481018390526000916001600160a01b03169063ec833b0c9060440160206040518083038186803b158015611d0e57600080fd5b505afa158015611d22573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061118591906125f9565b6004805460405163163c4b3160e31b81529182018390526000916001600160a01b039091169063b1e2598890602401610b9a565b60055460408051630f1d354d60e41b815290516000926001600160a01b03169163f1d354d0916004808301926020929190829003018186803b1580156109dd57600080fd5b60008054604051630f6b3e7d60e41b815260048101849052620100009091046001600160a01b03169063f6b3e7d090602401610b9a565b600354604051600162c0c77d60e01b03198152600481018390526000916001600160a01b03169063ff3f388390602401610b9a565b60008054604051631c2d8fb360e31b815260048101849052620100009091046001600160a01b03169063e16c7d989060240160206040518083038186803b158015611e7557600080fd5b505afa158015611e89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ead91906125a5565b90506001600160a01b0381166109695760405162461bcd60e51b815260206004820152602560248201527f4552524f523a4352432d3030343a434f4e54524143545f4e4f545f5245474953604482015264151154915160da1b6064820152608401610d63565b600054610100900460ff16611f7e5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610d63565b611f906542756e646c6560d01b611e2b565b600280546001600160a01b0319166001600160a01b0392909216919091179055611fc56810dbdb5c1bdb995b9d60ba1b611e2b565b600380546001600160a01b0319166001600160a01b0392909216919091179055611ff765506f6c69637960d01b611e2b565b600480546001600160a01b0319166001600160a01b039290921691909117905561202763141bdbdb60e21b611e2b565b600580546001600160a01b0319166001600160a01b039290921691909117905561205b67547265617375727960c01b611e2b565b600680546001600160a01b0319166001600160a01b0392909216919091179055612083612085565b565b60408051808201909152601481527308ae8d0cae4caeada409ac2d2dcdccae85e8aa8960631b602080830191825260016000526007905290516120e9917fb39221ace053465ec3453ce2b36430bd138b997ecea25c1043da0c366812b82891612465565b5060408051808201909152600a81526908edecae4d8d25e8aa8960b31b60208083019182526005600052600790529051612144917fbcdda56b5d08466ec462cbbe0adfa57cb0a15fcc8940ef68f702f21b787bc93591612465565b506040805180820190915260078082526647616e6163686560c81b602080840191825261053960005291909152905161219e917f96a76633116ac3161b66b4be70f114c9a245f4bbf414dc7a4d0edce8c01734cf91612465565b5060408051808201909152600b81526a476e6f7369732f7844616960a81b602080830191825260646000526007905290516121fa917f06179e496907eb3333fef2ed2194553681badbb6d717316349bf33d21ec47e1291612465565b5060408051808201909152600a815269536f6b6f6c2f53504f4160b01b6020808301918252604d600052600790529051612255917f58f3d94c4a880e721e755344405d3fe6076875bf5b3ad388d0a326a85bcabfb591612465565b50604080518082019091526015815274506f6c79676f6e204d61696e6e65742f4d4154494360581b602080830191825260896000526007905290516122bb917f65420a8d28339aeca441a0c94a464f6387b468f3f5ea5c247a6df59a5f7b886691612465565b5060408051808201909152600c81526b4d756d6261692f4d4154494360a01b6020808301918252611f41600052600790529051612319917f4d67172c71df6b75e948764b65521db84c0c61e94d5f3739b666417e9471e58491612465565b50604080518082019091526016815275082ecc2d8c2dcc6d0ca40865a86d0c2d2dc5e82ac82b60531b602080830191825261a86a600052600790529051612381917fa4356065248d86930c73e944e85f9d029fb0f52c0b8312d1a61bfbc9797ef51491612465565b5060408051808201909152601b81527f4176616c616e6368652046756a6920546573746e65742f415641580000000000602080830191825261a8696000526007905290516123f0917f57a00da22bfc0a372532b5dfacb7ddf387626f66de87422d191e09ea7493495691612465565b50565b6040518061014001604052806000815260200160008152602001600081526020016000600381111561243557634e487b7160e01b600052602160045260246000fd5b81526020016060815260200160008152602001600081526020016000815260200160008152602001600081525090565b82805461247190612dd1565b90600052602060002090601f01602090048101928261249357600085556124d9565b82601f106124ac57805160ff19168380011785556124d9565b828001600101855582156124d9579182015b828111156124d95782518255916020019190600101906124be565b506124e59291506124e9565b5090565b5b808211156124e557600081556001016124ea565b805161096981612e58565b600082601f830112612519578081fd5b815167ffffffffffffffff81111561253357612533612e22565b612546601f8201601f1916602001612d4d565b81815284602083860101111561255a578283fd5b61256b826020830160208701612da1565b949350505050565b805161096981612e6d565b805161096981612e7a565b60006020828403121561259a578081fd5b813561118581612e58565b6000602082840312156125b6578081fd5b815161118581612e58565b6000602082840312156125d2578081fd5b81518015158114611185578182fd5b6000602082840312156125f2578081fd5b5035919050565b60006020828403121561260a578081fd5b5051919050565b60008060408385031215612623578081fd5b82359150602083013561263581612e58565b809150509250929050565b60008060408385031215612652578182fd5b50508035926020909101359150565b600060208284031215612672578081fd5b815160078110611185578182fd5b600060208284031215612691578081fd5b815161118581612e7a565b6000602082840312156126ad578081fd5b815167ffffffffffffffff808211156126c4578283fd5b9083019060c082860312156126d7578283fd5b6126e160c0612d4d565b82516126ec81612e6d565b808252506020830151602082015260408301516040820152606083015182811115612715578485fd5b61272187828601612509565b6060830152506080830151608082015260a083015160a082015280935050505092915050565b600060208284031215612758578081fd5b815167ffffffffffffffff8082111561276f578283fd5b8184019150610140808387031215612785578384fd5b61278e81612d4d565b90508251815260208301516020820152604083015160408201526127b460608401612573565b60608201526080830151828111156127ca578485fd5b6127d687828601612509565b60808301525060a0838101519082015260c0808401519082015260e0808401519082015261010080840151908201526101209283015192810192909252509392505050565b60006020828403121561282c578081fd5b815167ffffffffffffffff80821115612843578283fd5b9083019060c08286031215612856578283fd5b61286060c0612d4d565b825161286b81612e58565b8152602083810151908201526128836040840161257e565b6040820152606083015182811115612715578485fd5b6000602082840312156128aa578081fd5b815167ffffffffffffffff808211156128c1578283fd5b9083019060c082860312156128d4578283fd5b6128de60c0612d4d565b825181526020830151600281106128f3578485fd5b602082015260408381015190820152606083015182811115612715578485fd5b6000610120808385031215612926578182fd5b61292f81612d4d565b905061293a8361257e565b81526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015160e08201526101008084015181830152508091505092915050565b60006101608083850312156129ab578182fd5b6129b481612d4d565b9050825181526129c6602084016124fe565b60208201526129d7604084016124fe565b6040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015160e08201526101008084015181830152506101208084015181830152506101408084015181830152508091505092915050565b60008151808452612a54816020860160208601612da1565b601f01601f19169290920160200192915050565b612a7181612e38565b9052565b6000602082526111856020830184612a3c565b6020810160078310612a9c57612a9c612e0c565b91905290565b60208101612a9c83612e48565b6000602082528251612ac081612e38565b806020840152506020830151604083015260408301516060830152606083015160c06080840152612af460e0840182612a3c565b9050608084015160a084015260a084015160c08401528091505092915050565b6000602082528251602083015260208301516040830152604083015160608301526060830151612b476080840182612a68565b5060808301516101408060a0850152612b64610160850183612a3c565b915060a085015160c085015260c085015160e085015260e0850151610100818187015280870151915050610120818187015280870151838701525050508091505092915050565b60006020825260018060a01b038351166020830152602083015160408301526040830151612bd881612e48565b80606084015250606083015160c06080840152612af460e0840182612a3c565b60006020825282516020830152602083015160028110612c1a57612c1a612e0c565b8060408401525060408301516060830152606083015160c06080840152612af460e0840182612a3c565b8151610120820190612c5581612e48565b808352506020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e083015160e083015261010080840151818401525092915050565b81518152602080830151610160830191612cd5908401826001600160a01b03169052565b506040830151612cf060408401826001600160a01b03169052565b50606083015160608301526080830151608083015260a083015160a083015260c083015160c083015260e083015160e083015261010080840151818401525061012080840151818401525061014080840151818401525092915050565b604051601f8201601f1916810167ffffffffffffffff81118282101715612d7657612d76612e22565b604052919050565b600082821015612d9c57634e487b7160e01b81526011600452602481fd5b500390565b60005b83811015612dbc578181015183820152602001612da4565b83811115612dcb576000848401525b50505050565b600281046001821680612de557607f821691505b60208210811415612e0657634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b600481106123f0576123f0612e0c565b600381106123f0576123f0612e0c565b6001600160a01b03811681146123f057600080fd5b600481106123f057600080fd5b600381106123f057600080fdfea26469706673582212204e1660b0e27116d5ed491a1c24d0670440ed1a3122fbb29c776b62b119d4843264736f6c63430008020033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.