Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 11 from a total of 11 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Redeem | 12188067 | 1323 days ago | IN | 0 ETH | 0.03149879 | ||||
Cancel Request F... | 10628616 | 1563 days ago | IN | 0.00158881 ETH | 0.00998666 | ||||
Request Investme... | 10618290 | 1565 days ago | IN | 0.01184116 ETH | 0.011062 | ||||
Redeem | 10481539 | 1586 days ago | IN | 0 ETH | 0.02191936 | ||||
Execute Request ... | 10475859 | 1587 days ago | IN | 0.02036118 ETH | 0.04573617 | ||||
Request Investme... | 10472177 | 1587 days ago | IN | 0.01745328 ETH | 0.01306886 | ||||
Execute Request ... | 9560271 | 1729 days ago | IN | 0.00647377 ETH | 0.00660172 | ||||
Redeem | 9560268 | 1729 days ago | IN | 0 ETH | 0.00187433 | ||||
Request Investme... | 9560124 | 1729 days ago | IN | 0.01319201 ETH | 0.0028728 | ||||
Execute Request ... | 9560098 | 1729 days ago | IN | 0.00605634 ETH | 0.00432613 | ||||
Request Investme... | 9560089 | 1729 days ago | IN | 0.01319175 ETH | 0.00272256 |
Latest 21 internal transactions
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
10628616 | 1563 days ago | 0.00101818 ETH | ||||
10628616 | 1563 days ago | 0.00057062 ETH | ||||
10628616 | 1563 days ago | 0.01 ETH | ||||
10618290 | 1565 days ago | 0.00101796 ETH | ||||
10618290 | 1565 days ago | 0.0008232 ETH | ||||
10475859 | 1587 days ago | 0.00513124 ETH | ||||
10475859 | 1587 days ago | 0.01522993 ETH | ||||
10475859 | 1587 days ago | 0.01 ETH | ||||
10472177 | 1587 days ago | 0.00412098 ETH | ||||
10472177 | 1587 days ago | 0.0033323 ETH | ||||
9560271 | 1729 days ago | 0.00202169 ETH | ||||
9560271 | 1729 days ago | 0.00445208 ETH | ||||
9560271 | 1729 days ago | 0.01 ETH | ||||
9560124 | 1729 days ago | 0.00176494 ETH | ||||
9560124 | 1729 days ago | 0.00142706 ETH | ||||
9560098 | 1729 days ago | 0.00198374 ETH | ||||
9560098 | 1729 days ago | 0.00407259 ETH | ||||
9560098 | 1729 days ago | 0.01 ETH | ||||
9560089 | 1729 days ago | 0.00176468 ETH | ||||
9560089 | 1729 days ago | 0.00142706 ETH | ||||
9560053 | 1729 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Similar Match Source Code This contract matches the deployed Bytecode of the Source Code for Contract 0x0F74ce61...A84f00286 The constructor portion of the code might be different and could alter the actual behaviour of the contract
Contract Name:
Participation
Compiler Version
v0.6.1+commit.e6f7d5a4
Contract Source Code (Solidity Standard Json-Input format)
pragma solidity 0.6.1; import "../vault/Vault.sol"; import "../shares/Shares.sol"; import "../policies/PolicyManager.sol"; import "../hub/Spoke.sol"; import "../accounting/Accounting.sol"; import "../../prices/IPriceSource.sol"; import "../../factory/Factory.sol"; import "../../engine/AmguConsumer.sol"; import "../../dependencies/token/IERC20.sol"; import "../../dependencies/DSMath.sol"; import "../../dependencies/TokenUser.sol"; /// @notice Entry and exit point for investors contract Participation is TokenUser, AmguConsumer, Spoke { event EnableInvestment (address[] asset); event DisableInvestment (address[] assets); event InvestmentRequest ( address indexed requestOwner, address indexed investmentAsset, uint requestedShares, uint investmentAmount ); event RequestExecution ( address indexed requestOwner, address indexed executor, address indexed investmentAsset, uint investmentAmount, uint requestedShares ); event CancelRequest ( address indexed requestOwner ); event Redemption ( address indexed redeemer, address[] assets, uint[] assetQuantities, uint redeemedShares ); struct Request { address investmentAsset; uint investmentAmount; uint requestedShares; uint timestamp; } uint constant public SHARES_DECIMALS = 18; uint constant public REQUEST_LIFESPAN = 1 days; mapping (address => Request) public requests; mapping (address => bool) public investAllowed; mapping (address => bool) public hasInvested; // for information purposes only (read) address[] public historicalInvestors; // for information purposes only (read) constructor(address _hub, address[] memory _defaultAssets, address _registry) public Spoke(_hub) { routes.registry = _registry; _enableInvestment(_defaultAssets); } receive() external payable {} function _enableInvestment(address[] memory _assets) internal { for (uint i = 0; i < _assets.length; i++) { require( Registry(routes.registry).assetIsRegistered(_assets[i]), "Asset not registered" ); investAllowed[_assets[i]] = true; } emit EnableInvestment(_assets); } function enableInvestment(address[] calldata _assets) external auth { _enableInvestment(_assets); } function disableInvestment(address[] calldata _assets) external auth { for (uint i = 0; i < _assets.length; i++) { investAllowed[_assets[i]] = false; } emit DisableInvestment(_assets); } function hasRequest(address _who) public view returns (bool) { return requests[_who].timestamp > 0; } function hasExpiredRequest(address _who) public view returns (bool) { return block.timestamp > add(requests[_who].timestamp, REQUEST_LIFESPAN); } /// @notice Whether request is OK and invest delay is being respected /// @dev Request valid if price update happened since request and not expired /// @dev If no shares exist and not expired, request can be executed immediately function hasValidRequest(address _who) public view returns (bool) { IPriceSource priceSource = IPriceSource(priceSource()); bool delayRespectedOrNoShares = requests[_who].timestamp < priceSource.getLastUpdate() || Shares(routes.shares).totalSupply() == 0; return hasRequest(_who) && delayRespectedOrNoShares && !hasExpiredRequest(_who) && requests[_who].investmentAmount > 0 && requests[_who].requestedShares > 0; } function requestInvestment( uint requestedShares, uint investmentAmount, address investmentAsset ) external notShutDown payable amguPayable(true) onlyInitialized { PolicyManager(routes.policyManager).preValidate( msg.sig, [msg.sender, address(0), address(0), investmentAsset, address(0)], [uint(0), uint(0), uint(0)], bytes32(0) ); require( investAllowed[investmentAsset], "Investment not allowed in this asset" ); safeTransferFrom( investmentAsset, msg.sender, address(this), investmentAmount ); require( requests[msg.sender].timestamp == 0, "Only one request can exist at a time" ); requests[msg.sender] = Request({ investmentAsset: investmentAsset, investmentAmount: investmentAmount, requestedShares: requestedShares, timestamp: block.timestamp }); PolicyManager(routes.policyManager).postValidate( msg.sig, [msg.sender, address(0), address(0), investmentAsset, address(0)], [uint(0), uint(0), uint(0)], bytes32(0) ); emit InvestmentRequest( msg.sender, investmentAsset, requestedShares, investmentAmount ); } function _cancelRequestFor(address requestOwner) internal { require(hasRequest(requestOwner), "No request to cancel"); IPriceSource priceSource = IPriceSource(priceSource()); Request memory request = requests[requestOwner]; require( !priceSource.hasValidPrice(request.investmentAsset) || hasExpiredRequest(requestOwner) || hub.isShutDown(), "No cancellation condition was met" ); IERC20 investmentAsset = IERC20(request.investmentAsset); uint investmentAmount = request.investmentAmount; delete requests[requestOwner]; msg.sender.transfer(Registry(routes.registry).incentive()); safeTransfer(address(investmentAsset), requestOwner, investmentAmount); emit CancelRequest(requestOwner); } /// @notice Can only cancel when no price, request expired or fund shut down /// @dev Only request owner can cancel their request function cancelRequest() external payable amguPayable(false) { _cancelRequestFor(msg.sender); } function cancelRequestFor(address requestOwner) external payable amguPayable(false) { _cancelRequestFor(requestOwner); } function executeRequestFor(address requestOwner) external notShutDown amguPayable(false) payable { Request memory request = requests[requestOwner]; require( hasValidRequest(requestOwner), "No valid request for this address" ); FeeManager(routes.feeManager).rewardManagementFee(); uint totalShareCostInInvestmentAsset = Accounting(routes.accounting) .getShareCostInAsset( request.requestedShares, request.investmentAsset ); require( totalShareCostInInvestmentAsset <= request.investmentAmount, "Invested amount too low" ); // send necessary amount of investmentAsset to vault safeTransfer( request.investmentAsset, routes.vault, totalShareCostInInvestmentAsset ); uint investmentAssetChange = sub( request.investmentAmount, totalShareCostInInvestmentAsset ); // return investmentAsset change to request owner if (investmentAssetChange > 0) { safeTransfer( request.investmentAsset, requestOwner, investmentAssetChange ); } msg.sender.transfer(Registry(routes.registry).incentive()); Shares(routes.shares).createFor(requestOwner, request.requestedShares); Accounting(routes.accounting).addAssetToOwnedAssets(request.investmentAsset); if (!hasInvested[requestOwner]) { hasInvested[requestOwner] = true; historicalInvestors.push(requestOwner); } emit RequestExecution( requestOwner, msg.sender, request.investmentAsset, request.investmentAmount, request.requestedShares ); delete requests[requestOwner]; } function getOwedPerformanceFees(uint shareQuantity) public returns (uint remainingShareQuantity) { Shares shares = Shares(routes.shares); uint totalPerformanceFee = FeeManager(routes.feeManager).performanceFeeAmount(); // The denominator is augmented because performanceFeeAmount() accounts for inflation // Since shares are directly transferred, we don't need to account for inflation in this case uint performanceFeePortion = mul( totalPerformanceFee, shareQuantity ) / add(shares.totalSupply(), totalPerformanceFee); return performanceFeePortion; } /// @dev "Happy path" (no asset throws & quantity available) /// @notice Redeem all shares and across all assets function redeem() external { uint ownedShares = Shares(routes.shares).balanceOf(msg.sender); redeemQuantity(ownedShares); } /// @notice Redeem shareQuantity across all assets function redeemQuantity(uint shareQuantity) public { address[] memory assetList; assetList = Accounting(routes.accounting).getOwnedAssets(); redeemWithConstraints(shareQuantity, assetList); } // TODO: reconsider the scenario where the user has enough funds to force shutdown on a large trade (any way around this?) /// @dev Redeem only selected assets (used only when an asset throws) function redeemWithConstraints(uint shareQuantity, address[] memory requestedAssets) public { Shares shares = Shares(routes.shares); require( shares.balanceOf(msg.sender) >= shareQuantity && shares.balanceOf(msg.sender) > 0, "Sender does not have enough shares to fulfill request" ); uint owedPerformanceFees = 0; if ( IPriceSource(priceSource()).hasValidPrices(requestedAssets) && msg.sender != hub.manager() ) { FeeManager(routes.feeManager).rewardManagementFee(); owedPerformanceFees = getOwedPerformanceFees(shareQuantity); shares.destroyFor(msg.sender, owedPerformanceFees); shares.createFor(hub.manager(), owedPerformanceFees); } uint remainingShareQuantity = sub(shareQuantity, owedPerformanceFees); address ofAsset; uint[] memory ownershipQuantities = new uint[](requestedAssets.length); address[] memory redeemedAssets = new address[](requestedAssets.length); // Check whether enough assets held by fund Accounting accounting = Accounting(routes.accounting); for (uint i = 0; i < requestedAssets.length; ++i) { ofAsset = requestedAssets[i]; require( accounting.isInAssetList(ofAsset), "Requested asset not in asset list" ); for (uint j = 0; j < redeemedAssets.length; j++) { require( ofAsset != redeemedAssets[j], "Asset can only be redeemed once" ); } redeemedAssets[i] = ofAsset; uint quantityHeld = accounting.assetHoldings(ofAsset); if (quantityHeld == 0) continue; // participant's ownership percentage of asset holdings ownershipQuantities[i] = mul(quantityHeld, remainingShareQuantity) / shares.totalSupply(); } shares.destroyFor(msg.sender, remainingShareQuantity); // Transfer owned assets for (uint k = 0; k < requestedAssets.length; ++k) { ofAsset = requestedAssets[k]; if (ownershipQuantities[k] == 0) { continue; } else { Vault(routes.vault).withdraw(ofAsset, ownershipQuantities[k]); safeTransfer(ofAsset, msg.sender, ownershipQuantities[k]); } } emit Redemption( msg.sender, requestedAssets, ownershipQuantities, remainingShareQuantity ); } function getHistoricalInvestors() external view returns (address[] memory) { return historicalInvestors; } function engine() public view override(AmguConsumer, Spoke) returns (address) { return Spoke.engine(); } function mlnToken() public view override(AmguConsumer, Spoke) returns (address) { return Spoke.mlnToken(); } function priceSource() public view override(AmguConsumer, Spoke) returns (address) { return Spoke.priceSource(); } function registry() public view override(AmguConsumer, Spoke) returns (address) { return Spoke.registry(); } } contract ParticipationFactory is Factory { event NewInstance( address indexed hub, address indexed instance, address[] defaultAssets, address registry ); function createInstance(address _hub, address[] calldata _defaultAssets, address _registry) external returns (address) { address participation = address( new Participation(_hub, _defaultAssets, _registry) ); childExists[participation] = true; emit NewInstance(_hub, participation, _defaultAssets, _registry); return participation; } }
pragma solidity 0.6.1; import "../hub/Spoke.sol"; import "../../factory/Factory.sol"; import "../../dependencies/TokenUser.sol"; /// @notice Dumb custody component contract Vault is TokenUser, Spoke { constructor(address _hub) public Spoke(_hub) {} function withdraw(address token, uint amount) external auth { safeTransfer(token, msg.sender, amount); } } contract VaultFactory is Factory { function createInstance(address _hub) external returns (address) { address vault = address(new Vault(_hub)); childExists[vault] = true; emit NewInstance(_hub, vault); return vault; } }
pragma solidity 0.6.1; import "../hub/Spoke.sol"; import "../../dependencies/token/StandardToken.sol"; import "../../factory/Factory.sol"; contract Shares is Spoke, StandardToken { string public symbol; string public name; uint8 public decimals; constructor(address _hub) public Spoke(_hub) { name = hub.name(); symbol = "MLNF"; decimals = 18; } function createFor(address who, uint amount) public auth { _mint(who, amount); } function destroyFor(address who, uint amount) public auth { _burn(who, amount); } function transfer(address to, uint amount) public override returns (bool) { revert("Unimplemented"); } function transferFrom( address from, address to, uint amount ) public override returns (bool) { revert("Unimplemented"); } function approve(address spender, uint amount) public override returns (bool) { revert("Unimplemented"); } function increaseApproval( address spender, uint amount ) public override returns (bool) { revert("Unimplemented"); } function decreaseApproval( address spender, uint amount ) public override returns (bool) { revert("Unimplemented"); } } contract SharesFactory is Factory { function createInstance(address _hub) external returns (address) { address shares = address(new Shares(_hub)); childExists[shares] = true; emit NewInstance(_hub, shares); return shares; } }
pragma solidity 0.6.1; import "../../factory/Factory.sol"; import "../hub/Spoke.sol"; import "./IPolicy.sol"; contract PolicyManager is Spoke { event Registration( bytes4 indexed sig, IPolicy.Applied position, address indexed policy ); struct Entry { IPolicy[] pre; IPolicy[] post; } mapping(bytes4 => Entry) policies; constructor (address _hub) public Spoke(_hub) {} function register(bytes4 sig, address _policy) public auth { IPolicy.Applied position = IPolicy(_policy).position(); if (position == IPolicy.Applied.pre) { policies[sig].pre.push(IPolicy(_policy)); } else if (position == IPolicy.Applied.post) { policies[sig].post.push(IPolicy(_policy)); } else { revert("Only pre and post allowed"); } emit Registration(sig, position, _policy); } function batchRegister(bytes4[] memory sig, address[] memory _policies) public auth { require(sig.length == _policies.length, "Arrays lengths unequal"); for (uint i = 0; i < sig.length; i++) { register(sig[i], _policies[i]); } } function PoliciesToAddresses(IPolicy[] storage _policies) internal view returns (address[] memory) { address[] memory res = new address[](_policies.length); for(uint i = 0; i < _policies.length; i++) { res[i] = address(_policies[i]); } return res; } function getPoliciesBySig(bytes4 sig) public view returns (address[] memory, address[] memory) { return (PoliciesToAddresses(policies[sig].pre), PoliciesToAddresses(policies[sig].post)); } modifier isValidPolicyBySig(bytes4 sig, address[5] memory addresses, uint[3] memory values, bytes32 identifier) { preValidate(sig, addresses, values, identifier); _; postValidate(sig, addresses, values, identifier); } modifier isValidPolicy(address[5] memory addresses, uint[3] memory values, bytes32 identifier) { preValidate(msg.sig, addresses, values, identifier); _; postValidate(msg.sig, addresses, values, identifier); } function preValidate(bytes4 sig, address[5] memory addresses, uint[3] memory values, bytes32 identifier) public { validate(policies[sig].pre, sig, addresses, values, identifier); } function postValidate(bytes4 sig, address[5] memory addresses, uint[3] memory values, bytes32 identifier) public { validate(policies[sig].post, sig, addresses, values, identifier); } function validate(IPolicy[] storage aux, bytes4 sig, address[5] memory addresses, uint[3] memory values, bytes32 identifier) internal { for(uint i = 0; i < aux.length; i++) { require( aux[i].rule(sig, addresses, values, identifier), string(abi.encodePacked("Rule evaluated to false: ", aux[i].identifier())) ); } } } contract PolicyManagerFactory is Factory { function createInstance(address _hub) external returns (address) { address policyManager = address(new PolicyManager(_hub)); childExists[policyManager] = true; emit NewInstance(_hub, policyManager); return policyManager; } }
pragma solidity 0.6.1; import "./Hub.sol"; import "../../dependencies/DSAuth.sol"; /// @notice Has one Hub contract Spoke is DSAuth { Hub public hub; Hub.Routes public routes; bool public initialized; modifier onlyInitialized() { require(initialized, "Component not yet initialized"); _; } modifier notShutDown() { require(!hub.isShutDown(), "Hub is shut down"); _; } constructor(address _hub) public { hub = Hub(_hub); setAuthority(hub); setOwner(address(hub)); // temporary, to allow initialization } function initialize(address[11] calldata _spokes) external auth { require(msg.sender == address(hub)); require(!initialized, "Already initialized"); routes = Hub.Routes( _spokes[0], _spokes[1], _spokes[2], _spokes[3], _spokes[4], _spokes[5], _spokes[6], _spokes[7], _spokes[8], _spokes[9], _spokes[10] ); initialized = true; setOwner(address(0)); } function engine() public view virtual returns (address) { return routes.engine; } function mlnToken() public view virtual returns (address) { return routes.mlnToken; } function priceSource() public view virtual returns (address) { return hub.priceSource(); } function version() public view virtual returns (address) { return routes.version; } function registry() public view virtual returns (address) { return routes.registry; } }
pragma solidity 0.6.1; import "../../dependencies/token/StandardToken.sol"; import "../../factory/Factory.sol"; import "../../prices/IPriceSource.sol"; import "../fees/FeeManager.sol"; import "../hub/Spoke.sol"; import "../shares/Shares.sol"; import "../trading/ITrading.sol"; import "../vault/Vault.sol"; import "../../engine/AmguConsumer.sol"; contract Accounting is AmguConsumer, Spoke { event AssetAddition(address indexed asset); event AssetRemoval(address indexed asset); struct Calculations { uint gav; uint nav; uint allocatedFees; uint totalSupply; uint timestamp; } uint constant public MAX_OWNED_ASSETS = 20; address[] public ownedAssets; mapping (address => bool) public isInAssetList; uint public constant SHARES_DECIMALS = 18; address public NATIVE_ASSET; address public DENOMINATION_ASSET; uint public DENOMINATION_ASSET_DECIMALS; uint public DEFAULT_SHARE_PRICE; Calculations public atLastAllocation; constructor(address _hub, address _denominationAsset, address _nativeAsset) public Spoke(_hub) { DENOMINATION_ASSET = _denominationAsset; NATIVE_ASSET = _nativeAsset; DENOMINATION_ASSET_DECIMALS = ERC20WithFields(DENOMINATION_ASSET).decimals(); DEFAULT_SHARE_PRICE = 10 ** uint(DENOMINATION_ASSET_DECIMALS); } function getOwnedAssetsLength() external view returns (uint256) { return ownedAssets.length; } function getOwnedAssets() external view returns (address[] memory) { return ownedAssets; } function assetHoldings(address _asset) public returns (uint256) { return add( uint256(ERC20WithFields(_asset).balanceOf(routes.vault)), ITrading(routes.trading).updateAndGetQuantityBeingTraded(_asset) ); } /// @dev Returns sparse array function getFundHoldings() external returns (uint[] memory, address[] memory) { uint[] memory _quantities = new uint[](ownedAssets.length); address[] memory _assets = new address[](ownedAssets.length); for (uint i = 0; i < ownedAssets.length; i++) { address ofAsset = ownedAssets[i]; // assetHoldings formatting: mul(exchangeHoldings, 10 ** assetDecimal) uint quantityHeld = assetHoldings(ofAsset); _assets[i] = ofAsset; _quantities[i] = quantityHeld; } return (_quantities, _assets); } function calcAssetGAV(address _queryAsset) external returns (uint) { uint queryAssetQuantityHeld = assetHoldings(_queryAsset); return IPriceSource(priceSource()).convertQuantity( queryAssetQuantityHeld, _queryAsset, DENOMINATION_ASSET ); } // prices are quoted in DENOMINATION_ASSET so they use denominationDecimals function calcGav() public returns (uint gav) { for (uint i = 0; i < ownedAssets.length; ++i) { address asset = ownedAssets[i]; // assetHoldings formatting: mul(exchangeHoldings, 10 ** assetDecimals) uint quantityHeld = assetHoldings(asset); // Dont bother with the calculations if the balance of the asset is 0 if (quantityHeld == 0) { continue; } // gav as sum of mul(assetHoldings, assetPrice) with formatting: mul(mul(exchangeHoldings, exchangePrice), 10 ** shareDecimals) gav = add( gav, IPriceSource(priceSource()).convertQuantity( quantityHeld, asset, DENOMINATION_ASSET ) ); } return gav; } function calcNav(uint gav, uint unclaimedFeesInDenominationAsset) public pure returns (uint) { return sub(gav, unclaimedFeesInDenominationAsset); } function valuePerShare(uint totalValue, uint numShares) public pure returns (uint) { require(numShares > 0, "No shares to calculate value for"); return (totalValue * 10 ** uint(SHARES_DECIMALS)) / numShares; } function performCalculations() public returns ( uint gav, uint feesInDenominationAsset, // unclaimed amount uint feesInShares, // unclaimed amount uint nav, uint sharePrice, uint gavPerShareNetManagementFee ) { gav = calcGav(); uint totalSupply = Shares(routes.shares).totalSupply(); feesInShares = FeeManager(routes.feeManager).totalFeeAmount(); feesInDenominationAsset = (totalSupply == 0) ? 0 : mul(feesInShares, gav) / add(totalSupply, feesInShares); nav = calcNav(gav, feesInDenominationAsset); // The total share supply including the value of feesInDenominationAsset, measured in shares of this fund uint totalSupplyAccountingForFees = add(totalSupply, feesInShares); sharePrice = (totalSupply > 0) ? valuePerShare(gav, totalSupplyAccountingForFees) : DEFAULT_SHARE_PRICE; gavPerShareNetManagementFee = (totalSupply > 0) ? valuePerShare(gav, add(totalSupply, FeeManager(routes.feeManager).managementFeeAmount())) : DEFAULT_SHARE_PRICE; return (gav, feesInDenominationAsset, feesInShares, nav, sharePrice, gavPerShareNetManagementFee); } function calcGavPerShareNetManagementFee() public returns (uint gavPerShareNetManagementFee) { (,,,,,gavPerShareNetManagementFee) = performCalculations(); return gavPerShareNetManagementFee; } function getShareCostInAsset(uint _numShares, address _altAsset) external returns (uint) { uint denominationAssetQuantity = mul( _numShares, calcGavPerShareNetManagementFee() ) / 10 ** uint(SHARES_DECIMALS); return IPriceSource(priceSource()).convertQuantity( denominationAssetQuantity, DENOMINATION_ASSET, _altAsset ); } /// @notice Reward all fees and perform some updates /// @dev Anyone can call this function triggerRewardAllFees() external amguPayable(false) payable { updateOwnedAssets(); uint256 gav; uint256 feesInDenomination; uint256 feesInShares; uint256 nav; (gav, feesInDenomination, feesInShares, nav,,) = performCalculations(); uint256 totalSupply = Shares(routes.shares).totalSupply(); FeeManager(routes.feeManager).rewardAllFees(); atLastAllocation = Calculations({ gav: gav, nav: nav, allocatedFees: feesInDenomination, totalSupply: totalSupply, timestamp: block.timestamp }); } /// @dev Check holdings for all assets, and adjust list function updateOwnedAssets() public { for (uint i = 0; i < ownedAssets.length; i++) { address asset = ownedAssets[i]; if ( assetHoldings(asset) == 0 && !(asset == address(DENOMINATION_ASSET)) && ITrading(routes.trading).getOpenMakeOrdersAgainstAsset(asset) == 0 ) { _removeFromOwnedAssets(asset); } } } function addAssetToOwnedAssets(address _asset) external auth { _addAssetToOwnedAssets(_asset); } function removeFromOwnedAssets(address _asset) external auth { _removeFromOwnedAssets(_asset); } /// @dev Just pass if asset already in list function _addAssetToOwnedAssets(address _asset) internal { if (isInAssetList[_asset]) { return; } require( ownedAssets.length < MAX_OWNED_ASSETS, "Max owned asset limit reached" ); isInAssetList[_asset] = true; ownedAssets.push(_asset); emit AssetAddition(_asset); } /// @dev Just pass if asset not in list function _removeFromOwnedAssets(address _asset) internal { if (!isInAssetList[_asset]) { return; } isInAssetList[_asset] = false; for (uint i; i < ownedAssets.length; i++) { if (ownedAssets[i] == _asset) { ownedAssets[i] = ownedAssets[ownedAssets.length - 1]; ownedAssets.pop(); break; } } emit AssetRemoval(_asset); } function engine() public view override(AmguConsumer, Spoke) returns (address) { return Spoke.engine(); } function mlnToken() public view override(AmguConsumer, Spoke) returns (address) { return Spoke.mlnToken(); } function priceSource() public view override(AmguConsumer, Spoke) returns (address) { return Spoke.priceSource(); } function registry() public view override(AmguConsumer, Spoke) returns (address) { return Spoke.registry(); } } contract AccountingFactory is Factory { event NewInstance( address indexed hub, address indexed instance, address denominationAsset, address nativeAsset ); function createInstance(address _hub, address _denominationAsset, address _nativeAsset) external returns (address) { address accounting = address(new Accounting(_hub, _denominationAsset, _nativeAsset)); childExists[accounting] = true; emit NewInstance(_hub, accounting, _denominationAsset, _nativeAsset); return accounting; } }
pragma solidity 0.6.1; /// @notice Must return a value for an asset interface IPriceSource { function getQuoteAsset() external view returns (address); function getLastUpdate() external view returns (uint); /// @notice Returns false if asset not applicable, or price not recent function hasValidPrice(address) external view returns (bool); function hasValidPrices(address[] calldata) external view returns (bool); /// @notice Return the last known price, and when it was issued function getPrice(address _asset) external view returns (uint price, uint timestamp); function getPrices(address[] calldata _assets) external view returns (uint[] memory prices, uint[] memory timestamps); /// @notice Get price info, and revert if not valid function getPriceInfo(address _asset) external view returns (uint price, uint decimals); function getInvertedPriceInfo(address ofAsset) external view returns (uint price, uint decimals); function getReferencePriceInfo(address _base, address _quote) external view returns (uint referencePrice, uint decimal); function getOrderPriceInfo(address sellAsset, uint sellQuantity, uint buyQuantity) external view returns (uint orderPrice); function existsPriceOnAssetPair(address sellAsset, address buyAsset) external view returns (bool isExistent); function convertQuantity( uint fromAssetQuantity, address fromAsset, address toAsset ) external view returns (uint); }
pragma solidity 0.6.1; contract Factory { mapping (address => bool) public childExists; event NewInstance( address indexed hub, address indexed instance ); function isInstance(address _child) public view returns (bool) { return childExists[_child]; } }
pragma solidity 0.6.1; import "../dependencies/DSMath.sol"; import "../dependencies/token/IERC20.sol"; import "../prices/IPriceSource.sol"; import "../version/IVersion.sol"; import "./IEngine.sol"; import "../version/Registry.sol"; /// @notice Abstract contracts /// @notice inherit this to pay AMGU on a function call abstract contract AmguConsumer is DSMath { /// @dev each of these must be implemented by the inheriting contract function engine() public view virtual returns (address); function mlnToken() public view virtual returns (address); function priceSource() public view virtual returns (address); function registry() public view virtual returns (address); event AmguPaid(address indexed payer, uint256 totalAmguPaidInEth, uint256 amguChargableGas, uint256 incentivePaid); /// bool deductIncentive is used when sending extra eth beyond amgu modifier amguPayable(bool deductIncentive) { uint preGas = gasleft(); _; uint postGas = gasleft(); uint mlnPerAmgu = IEngine(engine()).getAmguPrice(); uint mlnQuantity = mul( mlnPerAmgu, sub(preGas, postGas) ); address nativeAsset = Registry(registry()).nativeAsset(); uint ethToPay = IPriceSource(priceSource()).convertQuantity( mlnQuantity, mlnToken(), nativeAsset ); uint incentiveAmount; if (deductIncentive) { incentiveAmount = Registry(registry()).incentive(); } else { incentiveAmount = 0; } require( msg.value >= add(ethToPay, incentiveAmount), "Insufficent AMGU and/or incentive" ); IEngine(engine()).payAmguInEther.value(ethToPay)(); require( msg.sender.send( sub( sub(msg.value, ethToPay), incentiveAmount ) ), "Refund failed" ); emit AmguPaid(msg.sender, ethToPay, sub(preGas, postGas), incentiveAmount); } }
pragma solidity 0.6.1; /** * @title ERC20 interface * @dev see https://github.com/ethereum/EIPs/issues/20 * Altered from https://github.com/OpenZeppelin/openzeppelin-solidity/blob/a466e76d26c394b1faa6e2797aefe34668566392/contracts/token/ERC20/ERC20.sol */ interface IERC20 { function totalSupply() external view returns (uint256); function balanceOf(address _who) external view returns (uint256); function allowance(address _owner, address _spender) external view returns (uint256); function transfer(address _to, uint256 _value) external returns (bool); function approve(address _spender, uint256 _value) external returns (bool); function transferFrom(address _from, address _to, uint256 _value) external returns (bool); event Transfer( address indexed from, address indexed to, uint256 value ); event Approval( address indexed owner, address indexed spender, uint256 value ); } /// @dev Just adds extra functions that we use elsewhere abstract contract ERC20WithFields is IERC20 { string public symbol; string public name; uint8 public decimals; }
/// DSMath.sol -- mixin for inline numerical wizardry // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >0.4.13; contract DSMath { function add(uint x, uint y) internal pure returns (uint z) { require((z = x + y) >= x, "ds-math-add-overflow"); } function sub(uint x, uint y) internal pure returns (uint z) { require((z = x - y) <= x, "ds-math-sub-underflow"); } function mul(uint x, uint y) internal pure returns (uint z) { require(y == 0 || (z = x * y) / y == x, "ds-math-mul-overflow"); } function min(uint x, uint y) internal pure returns (uint z) { return x <= y ? x : y; } function max(uint x, uint y) internal pure returns (uint z) { return x >= y ? x : y; } function imin(int x, int y) internal pure returns (int z) { return x <= y ? x : y; } function imax(int x, int y) internal pure returns (int z) { return x >= y ? x : y; } uint constant WAD = 10 ** 18; uint constant RAY = 10 ** 27; function wmul(uint x, uint y) internal pure returns (uint z) { z = add(mul(x, y), WAD / 2) / WAD; } function rmul(uint x, uint y) internal pure returns (uint z) { z = add(mul(x, y), RAY / 2) / RAY; } function wdiv(uint x, uint y) internal pure returns (uint z) { z = add(mul(x, WAD), y / 2) / y; } function rdiv(uint x, uint y) internal pure returns (uint z) { z = add(mul(x, RAY), y / 2) / y; } // This famous algorithm is called "exponentiation by squaring" // and calculates x^n with x as fixed-point and n as regular unsigned. // // It's O(log n), instead of O(n) for naive repeated multiplication. // // These facts are why it works: // // If n is even, then x^n = (x^2)^(n/2). // If n is odd, then x^n = x * x^(n-1), // and applying the equation for even x gives // x^n = x * (x^2)^((n-1) / 2). // // Also, EVM division is flooring and // floor[(n-1) / 2] = floor[n / 2]. // function rpow(uint x, uint n) internal pure returns (uint z) { z = n % 2 != 0 ? x : RAY; for (n /= 2; n != 0; n /= 2) { x = rmul(x, x); if (n % 2 != 0) { z = rmul(z, x); } } } }
pragma solidity 0.6.1; import "./token/IERC20.sol"; import "./DSMath.sol"; /// @notice Wrapper to ensure tokens are received contract TokenUser is DSMath { function safeTransfer( address _token, address _to, uint _value ) internal { uint receiverPreBalance = IERC20(_token).balanceOf(_to); IERC20(_token).transfer(_to, _value); uint receiverPostBalance = IERC20(_token).balanceOf(_to); require( add(receiverPreBalance, _value) == receiverPostBalance, "Receiver did not receive tokens in transfer" ); } function safeTransferFrom( address _token, address _from, address _to, uint _value ) internal { uint receiverPreBalance = IERC20(_token).balanceOf(_to); IERC20(_token).transferFrom(_from, _to, _value); uint receiverPostBalance = IERC20(_token).balanceOf(_to); require( add(receiverPreBalance, _value) == receiverPostBalance, "Receiver did not receive tokens in transferFrom" ); } }
pragma solidity 0.6.1; import "./IERC20.sol"; import "../SafeMath.sol"; /** * @title Standard ERC20 token * * @dev Implementation of the basic standard token. * https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md * Based on code by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol * Modified from https://github.com/OpenZeppelin/openzeppelin-solidity/blob/a466e76d26c394b1faa6e2797aefe34668566392/contracts/token/ERC20/StandardToken.sol */ contract StandardToken is IERC20 { using SafeMath for uint256; mapping (address => uint256) balances; mapping (address => mapping (address => uint256)) allowed; uint256 totalSupply_; /** * @dev Total number of tokens in existence */ function totalSupply() public view override returns (uint256) { return totalSupply_; } /** * @dev Gets the balance of the specified address. * @param _owner The address to query the the balance of. * @return An uint256 representing the amount owned by the passed address. */ function balanceOf(address _owner) public view override returns (uint256) { return balances[_owner]; } /** * @dev Function to check the amount of tokens that an owner allowed to a spender. * @param _owner address The address which owns the funds. * @param _spender address The address which will spend the funds. * @return A uint256 specifying the amount of tokens still available for the spender. */ function allowance( address _owner, address _spender ) public view override returns (uint256) { return allowed[_owner][_spender]; } /** * @dev Transfer token for a specified address * @param _to The address to transfer to. * @param _value The amount to be transferred. */ function transfer(address _to, uint256 _value) public virtual override returns (bool) { require(_value <= balances[msg.sender]); require(_to != address(0)); balances[msg.sender] = balances[msg.sender].sub(_value); balances[_to] = balances[_to].add(_value); emit Transfer(msg.sender, _to, _value); return true; } /** * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender. * 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 * @param _spender The address which will spend the funds. * @param _value The amount of tokens to be spent. */ function approve(address _spender, uint256 _value) public virtual override returns (bool) { allowed[msg.sender][_spender] = _value; emit Approval(msg.sender, _spender, _value); return true; } /** * @dev Transfer tokens from one address to another * @param _from address The address which you want to send tokens from * @param _to address The address which you want to transfer to * @param _value uint256 the amount of tokens to be transferred */ function transferFrom( address _from, address _to, uint256 _value ) public virtual override returns (bool) { require(_value <= balances[_from]); require(_value <= allowed[_from][msg.sender]); require(_to != address(0)); balances[_from] = balances[_from].sub(_value); balances[_to] = balances[_to].add(_value); allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value); emit Approval(_from, msg.sender, allowed[_from][msg.sender]); emit Transfer(_from, _to, _value); return true; } /** * @dev Increase the amount of tokens that an owner allowed to a spender. * approve should be called when allowed[_spender] == 0. To increment * allowed value is better to use this function to avoid 2 calls (and wait until * the first transaction is mined) * From MonolithDAO Token.sol * @param _spender The address which will spend the funds. * @param _addedValue The amount of tokens to increase the allowance by. */ function increaseApproval( address _spender, uint256 _addedValue ) public virtual returns (bool) { allowed[msg.sender][_spender] = (allowed[msg.sender][_spender].add(_addedValue)); emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]); return true; } /** * @dev Decrease the amount of tokens that an owner allowed to a spender. * approve should be called when allowed[_spender] == 0. To decrement * allowed value is better to use this function to avoid 2 calls (and wait until * the first transaction is mined) * From MonolithDAO Token.sol * @param _spender The address which will spend the funds. * @param _subtractedValue The amount of tokens to decrease the allowance by. */ function decreaseApproval( address _spender, uint256 _subtractedValue ) public virtual returns (bool) { uint256 oldValue = allowed[msg.sender][_spender]; if (_subtractedValue >= oldValue) { allowed[msg.sender][_spender] = 0; } else { allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue); } emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]); return true; } /** * @dev Internal function that mints an amount of the token and assigns it to * an account. This encapsulates the modification of balances such that the * proper events are emitted. * @param _account The account that will receive the created tokens. * @param _amount The amount that will be created. */ function _mint(address _account, uint256 _amount) internal { require(_account != address(0)); totalSupply_ = totalSupply_.add(_amount); balances[_account] = balances[_account].add(_amount); emit Transfer(address(0), _account, _amount); } /** * @dev Internal function that burns an amount of the token of a given * account. * @param _account The account whose tokens will be burnt. * @param _amount The amount that will be burnt. */ function _burn(address _account, uint256 _amount) internal { require(_account != address(0)); require(_amount <= balances[_account]); totalSupply_ = totalSupply_.sub(_amount); balances[_account] = balances[_account].sub(_amount); emit Transfer(_account, address(0), _amount); } /** * @dev Internal function that burns an amount of the token of a given * account, deducting from the sender's allowance for said account. Uses the * internal _burn function. * @param _account The account whose tokens will be burnt. * @param _amount The amount that will be burnt. */ function _burnFrom(address _account, uint256 _amount) internal { require(_amount <= allowed[_account][msg.sender]); allowed[_account][msg.sender] = allowed[_account][msg.sender].sub(_amount); emit Approval(_account, msg.sender, allowed[_account][msg.sender]); _burn(_account, _amount); } }
pragma solidity 0.6.1; interface IPolicy { enum Applied { pre, post } // In Trading context: // addresses: Order maker, Order taker, Order maker asset, Order taker asset, Exchange address // values: Maker token quantity, Taker token quantity, Fill Taker Quantity // In Participation context: // address[0]: Investor address, address[3]: Investment asset function rule(bytes4 sig, address[5] calldata addresses, uint[3] calldata values, bytes32 identifier) external returns (bool); function position() external view returns (Applied); function identifier() external view returns (string memory); }
pragma solidity 0.6.1; import "../../dependencies/DSGuard.sol"; import "./Spoke.sol"; import "../../version/Registry.sol"; /// @notice Router for communication between components /// @notice Has one or more Spokes contract Hub is DSGuard { event FundShutDown(); struct Routes { address accounting; address feeManager; address participation; address policyManager; address shares; address trading; address vault; address registry; address version; address engine; address mlnToken; } Routes public routes; address public manager; address public creator; string public name; bool public isShutDown; bool public fundInitialized; uint public creationTime; mapping (address => bool) public isSpoke; constructor(address _manager, string memory _name) public { creator = msg.sender; manager = _manager; name = _name; creationTime = block.timestamp; } modifier onlyCreator() { require(msg.sender == creator, "Only creator can do this"); _; } function shutDownFund() external { require(msg.sender == routes.version); isShutDown = true; emit FundShutDown(); } function initializeAndSetPermissions(address[11] calldata _spokes) external onlyCreator { require(!fundInitialized, "Fund is already initialized"); for (uint i = 0; i < _spokes.length; i++) { isSpoke[_spokes[i]] = true; } routes.accounting = _spokes[0]; routes.feeManager = _spokes[1]; routes.participation = _spokes[2]; routes.policyManager = _spokes[3]; routes.shares = _spokes[4]; routes.trading = _spokes[5]; routes.vault = _spokes[6]; routes.registry = _spokes[7]; routes.version = _spokes[8]; routes.engine = _spokes[9]; routes.mlnToken = _spokes[10]; Spoke(routes.accounting).initialize(_spokes); Spoke(routes.feeManager).initialize(_spokes); Spoke(routes.participation).initialize(_spokes); Spoke(routes.policyManager).initialize(_spokes); Spoke(routes.shares).initialize(_spokes); Spoke(routes.trading).initialize(_spokes); Spoke(routes.vault).initialize(_spokes); permit(routes.participation, routes.vault, bytes4(keccak256('withdraw(address,uint256)'))); permit(routes.trading, routes.vault, bytes4(keccak256('withdraw(address,uint256)'))); permit(routes.participation, routes.shares, bytes4(keccak256('createFor(address,uint256)'))); permit(routes.participation, routes.shares, bytes4(keccak256('destroyFor(address,uint256)'))); permit(routes.feeManager, routes.shares, bytes4(keccak256('createFor(address,uint256)'))); permit(routes.participation, routes.accounting, bytes4(keccak256('addAssetToOwnedAssets(address)'))); permit(routes.trading, routes.accounting, bytes4(keccak256('addAssetToOwnedAssets(address)'))); permit(routes.trading, routes.accounting, bytes4(keccak256('removeFromOwnedAssets(address)'))); permit(routes.accounting, routes.feeManager, bytes4(keccak256('rewardAllFees()'))); permit(manager, routes.policyManager, bytes4(keccak256('register(bytes4,address)'))); permit(manager, routes.policyManager, bytes4(keccak256('batchRegister(bytes4[],address[])'))); permit(manager, routes.participation, bytes4(keccak256('enableInvestment(address[])'))); permit(manager, routes.participation, bytes4(keccak256('disableInvestment(address[])'))); permit(manager, routes.trading, bytes4(keccak256('addExchange(address,address)'))); fundInitialized = true; } function vault() external view returns (address) { return routes.vault; } function accounting() external view returns (address) { return routes.accounting; } function priceSource() external view returns (address) { return Registry(routes.registry).priceSource(); } function participation() external view returns (address) { return routes.participation; } function trading() external view returns (address) { return routes.trading; } function shares() external view returns (address) { return routes.shares; } function registry() external view returns (address) { return routes.registry; } function version() external view returns (address) { return routes.version; } function policyManager() external view returns (address) { return routes.policyManager; } }
/// @notice Modified from DappHub (https://git.io/fpwrq) pragma solidity 0.6.1; abstract contract DSAuthority { function canCall( address src, address dst, bytes4 sig ) public view virtual returns (bool); } contract DSAuthEvents { event LogSetAuthority (address indexed authority); event LogSetOwner (address indexed owner); } contract DSAuth is DSAuthEvents { DSAuthority public authority; address public owner; constructor() public { owner = msg.sender; emit LogSetOwner(msg.sender); } function setOwner(address owner_) public auth { owner = owner_; emit LogSetOwner(owner); } function setAuthority(DSAuthority authority_) public auth { authority = authority_; emit LogSetAuthority(address(authority)); } modifier auth { require(isAuthorized(msg.sender, msg.sig), "ds-auth-unauthorized"); _; } function isAuthorized(address src, bytes4 sig) internal view returns (bool) { if (src == address(this)) { return true; } else if (src == owner) { return true; } else if (authority == DSAuthority(0)) { return false; } else { return authority.canCall(src, address(this), sig); } } }
pragma solidity 0.6.1; pragma experimental ABIEncoderV2; import "./IFee.sol"; import "../hub/Spoke.sol"; import "../shares/Shares.sol"; import "../../factory/Factory.sol"; import "../../version/Registry.sol"; import "../../dependencies/DSMath.sol"; import "./IFeeManager.sol"; /// @notice Manages and allocates fees for a particular fund contract FeeManager is DSMath, Spoke { event FeeReward(uint shareQuantity); event FeeRegistration(address fee); struct FeeInfo { address feeAddress; uint feeRate; uint feePeriod; } IFee[] public fees; mapping (address => bool) public feeIsRegistered; constructor(address _hub, address _denominationAsset, address[] memory _fees, uint[] memory _rates, uint[] memory _periods, address _registry) Spoke(_hub) public { for (uint i = 0; i < _fees.length; i++) { require( Registry(_registry).isFeeRegistered(_fees[i]), "Fee must be known to Registry" ); register(_fees[i], _rates[i], _periods[i], _denominationAsset); } if (fees.length > 0) { require( fees[0].identifier() == 0, "Management fee must be at 0 index" ); } if (fees.length > 1) { require( fees[1].identifier() == 1, "Performance fee must be at 1 index" ); } } function register(address feeAddress, uint feeRate, uint feePeriod, address denominationAsset) internal { require(!feeIsRegistered[feeAddress], "Fee already registered"); feeIsRegistered[feeAddress] = true; fees.push(IFee(feeAddress)); IFee(feeAddress).initializeForUser(feeRate, feePeriod, denominationAsset); // initialize state emit FeeRegistration(feeAddress); } function totalFeeAmount() external returns (uint total) { for (uint i = 0; i < fees.length; i++) { total = add(total, fees[i].feeAmount()); } return total; } /// @dev Shares to be inflated after update state function _rewardFee(IFee fee) internal { require(feeIsRegistered[address(fee)], "Fee is not registered"); uint rewardShares = fee.feeAmount(); fee.updateState(); Shares(routes.shares).createFor(hub.manager(), rewardShares); emit FeeReward(rewardShares); } function _rewardAllFees() internal { for (uint i = 0; i < fees.length; i++) { _rewardFee(fees[i]); } } /// @dev Used when calling from other components function rewardAllFees() public auth { _rewardAllFees(); } /// @dev Convenience function; anyone can reward management fee any time /// @dev Convention that management fee is 0 function rewardManagementFee() public { if (fees.length >= 1) _rewardFee(fees[0]); } /// @dev Convenience function /// @dev Convention that management fee is 0 function managementFeeAmount() external returns (uint) { if (fees.length < 1) return 0; return fees[0].feeAmount(); } /// @dev Convenience function /// @dev Convention that performace fee is 1 function performanceFeeAmount() external returns (uint) { if (fees.length < 2) return 0; return fees[1].feeAmount(); } } contract FeeManagerFactory is Factory { function createInstance( address _hub, address _denominationAsset, address[] memory _fees, uint[] memory _feeRates, uint[] memory _feePeriods, address _registry ) public returns (address) { address feeManager = address( new FeeManager(_hub, _denominationAsset, _fees, _feeRates, _feePeriods, _registry) ); childExists[feeManager] = true; emit NewInstance(_hub, feeManager); return feeManager; } }
pragma solidity 0.6.1; pragma experimental ABIEncoderV2; // TODO: Restore indexed params /// @notice Mediation between a Fund and exchanges interface ITrading { function callOnExchange( uint exchangeIndex, string calldata methodSignature, address[8] calldata orderAddresses, uint[8] calldata orderValues, bytes[4] calldata orderData, bytes32 identifier, bytes calldata signature ) external; function addOpenMakeOrder( address ofExchange, address ofSellAsset, address ofBuyAsset, address ofFeeAsset, uint orderId, uint expiryTime ) external; function removeOpenMakeOrder( address ofExchange, address ofSellAsset ) external; function updateAndGetQuantityBeingTraded(address _asset) external returns (uint256); function getOpenMakeOrdersAgainstAsset(address _asset) external view returns (uint256); } interface ITradingFactory { function createInstance( address _hub, address[] calldata _exchanges, address[] calldata _adapters, address _registry ) external returns (address); }
pragma solidity 0.6.1; interface IVersion { function shutDownFund(address) external; }
pragma solidity 0.6.1; interface IEngine { function payAmguInEther() external payable; function getAmguPrice() external view returns (uint256); }
pragma solidity 0.6.1; import "../dependencies/DSAuth.sol"; import "../fund/hub/Hub.sol"; import "../dependencies/token/IERC20.sol"; contract Registry is DSAuth { // EVENTS event AssetUpsert ( address indexed asset, string name, string symbol, uint decimals, string url, uint reserveMin, uint[] standards, bytes4[] sigs ); event ExchangeAdapterUpsert ( address indexed exchange, address indexed adapter, bool takesCustody, bytes4[] sigs ); event AssetRemoval (address indexed asset); event EfxWrapperRegistryChange(address indexed registry); event EngineChange(address indexed engine); event ExchangeAdapterRemoval (address indexed exchange); event IncentiveChange(uint incentiveAmount); event MGMChange(address indexed MGM); event MlnTokenChange(address indexed mlnToken); event NativeAssetChange(address indexed nativeAsset); event PriceSourceChange(address indexed priceSource); event VersionRegistration(address indexed version); // TYPES struct Asset { bool exists; string name; string symbol; uint decimals; string url; uint reserveMin; uint[] standards; bytes4[] sigs; } struct Exchange { bool exists; address exchangeAddress; bool takesCustody; bytes4[] sigs; } struct Version { bool exists; bytes32 name; } // CONSTANTS uint public constant MAX_REGISTERED_ENTITIES = 20; uint public constant MAX_FUND_NAME_BYTES = 66; // FIELDS mapping (address => Asset) public assetInformation; address[] public registeredAssets; // Mapping from adapter address to exchange Information (Adapters are unique) mapping (address => Exchange) public exchangeInformation; address[] public registeredExchangeAdapters; mapping (address => Version) public versionInformation; address[] public registeredVersions; mapping (address => bool) public isFeeRegistered; mapping (address => address) public fundsToVersions; mapping (bytes32 => bool) public versionNameExists; mapping (bytes32 => address) public fundNameHashToOwner; uint public incentive = 10 finney; address public priceSource; address public mlnToken; address public nativeAsset; address public engine; address public ethfinexWrapperRegistry; address public MGM; modifier onlyVersion() { require( versionInformation[msg.sender].exists, "Only a Version can do this" ); _; } // METHODS constructor(address _postDeployOwner) public { setOwner(_postDeployOwner); } // PUBLIC METHODS /// @notice Whether _name has only valid characters function isValidFundName(string memory _name) public pure returns (bool) { bytes memory b = bytes(_name); if (b.length > MAX_FUND_NAME_BYTES) return false; for (uint i; i < b.length; i++){ bytes1 char = b[i]; if( !(char >= 0x30 && char <= 0x39) && // 9-0 !(char >= 0x41 && char <= 0x5A) && // A-Z !(char >= 0x61 && char <= 0x7A) && // a-z !(char == 0x20 || char == 0x2D) && // space, dash !(char == 0x2E || char == 0x5F) && // period, underscore !(char == 0x2A) // * ) { return false; } } return true; } /// @notice Whether _user can use _name for their fund function canUseFundName(address _user, string memory _name) public view returns (bool) { bytes32 nameHash = keccak256(bytes(_name)); return ( isValidFundName(_name) && ( fundNameHashToOwner[nameHash] == address(0) || fundNameHashToOwner[nameHash] == _user ) ); } function reserveFundName(address _owner, string calldata _name) external onlyVersion { require(canUseFundName(_owner, _name), "Fund name cannot be used"); fundNameHashToOwner[keccak256(bytes(_name))] = _owner; } function registerFund(address _fund, address _owner, string calldata _name) external onlyVersion { require(canUseFundName(_owner, _name), "Fund name cannot be used"); fundsToVersions[_fund] = msg.sender; } /// @notice Registers an Asset information entry /// @dev Pre: Only registrar owner should be able to register /// @dev Post: Address _asset is registered /// @param _asset Address of asset to be registered /// @param _name Human-readable name of the Asset /// @param _symbol Human-readable symbol of the Asset /// @param _url Url for extended information of the asset /// @param _standards Integers of EIP standards this asset adheres to /// @param _sigs Function signatures for whitelisted asset functions function registerAsset( address _asset, string calldata _name, string calldata _symbol, string calldata _url, uint _reserveMin, uint[] calldata _standards, bytes4[] calldata _sigs ) external auth { require(registeredAssets.length < MAX_REGISTERED_ENTITIES); require(!assetInformation[_asset].exists); assetInformation[_asset].exists = true; registeredAssets.push(_asset); updateAsset( _asset, _name, _symbol, _url, _reserveMin, _standards, _sigs ); } /// @notice Register an exchange information entry (A mapping from exchange adapter -> Exchange information) /// @dev Adapters are unique so are used as the mapping key. There may be different adapters for same exchange (0x / Ethfinex) /// @dev Pre: Only registrar owner should be able to register /// @dev Post: Address _exchange is registered /// @param _exchange Address of the exchange for the adapter /// @param _adapter Address of exchange adapter /// @param _takesCustody Whether this exchange takes custody of tokens before trading /// @param _sigs Function signatures for whitelisted exchange functions function registerExchangeAdapter( address _exchange, address _adapter, bool _takesCustody, bytes4[] calldata _sigs ) external auth { require(!exchangeInformation[_adapter].exists, "Adapter already exists"); exchangeInformation[_adapter].exists = true; require(registeredExchangeAdapters.length < MAX_REGISTERED_ENTITIES, "Exchange limit reached"); registeredExchangeAdapters.push(_adapter); updateExchangeAdapter( _exchange, _adapter, _takesCustody, _sigs ); } /// @notice Versions cannot be removed from registry /// @param _version Address of the version contract /// @param _name Name of the version function registerVersion( address _version, bytes32 _name ) external auth { require(!versionInformation[_version].exists, "Version already exists"); require(!versionNameExists[_name], "Version name already exists"); versionInformation[_version].exists = true; versionNameExists[_name] = true; versionInformation[_version].name = _name; registeredVersions.push(_version); emit VersionRegistration(_version); } function setIncentive(uint _weiAmount) external auth { incentive = _weiAmount; emit IncentiveChange(_weiAmount); } function setPriceSource(address _priceSource) external auth { priceSource = _priceSource; emit PriceSourceChange(_priceSource); } function setMlnToken(address _mlnToken) external auth { mlnToken = _mlnToken; emit MlnTokenChange(_mlnToken); } function setNativeAsset(address _nativeAsset) external auth { nativeAsset = _nativeAsset; emit NativeAssetChange(_nativeAsset); } function setEngine(address _engine) external auth { engine = _engine; emit EngineChange(_engine); } function setMGM(address _MGM) external auth { MGM = _MGM; emit MGMChange(_MGM); } function setEthfinexWrapperRegistry(address _registry) external auth { ethfinexWrapperRegistry = _registry; emit EfxWrapperRegistryChange(_registry); } /// @notice Updates description information of a registered Asset /// @dev Pre: Owner can change an existing entry /// @dev Post: Changed Name, Symbol, URL and/or IPFSHash /// @param _asset Address of the asset to be updated /// @param _name Human-readable name of the Asset /// @param _symbol Human-readable symbol of the Asset /// @param _url Url for extended information of the asset function updateAsset( address _asset, string memory _name, string memory _symbol, string memory _url, uint _reserveMin, uint[] memory _standards, bytes4[] memory _sigs ) public auth { require(assetInformation[_asset].exists); Asset storage asset = assetInformation[_asset]; asset.name = _name; asset.symbol = _symbol; asset.decimals = ERC20WithFields(_asset).decimals(); asset.url = _url; asset.reserveMin = _reserveMin; asset.standards = _standards; asset.sigs = _sigs; emit AssetUpsert( _asset, _name, _symbol, asset.decimals, _url, _reserveMin, _standards, _sigs ); } function updateExchangeAdapter( address _exchange, address _adapter, bool _takesCustody, bytes4[] memory _sigs ) public auth { require(exchangeInformation[_adapter].exists, "Exchange with adapter doesn't exist"); Exchange storage exchange = exchangeInformation[_adapter]; exchange.exchangeAddress = _exchange; exchange.takesCustody = _takesCustody; exchange.sigs = _sigs; emit ExchangeAdapterUpsert( _exchange, _adapter, _takesCustody, _sigs ); } /// @notice Deletes an existing entry /// @dev Owner can delete an existing entry /// @param _asset address for which specific information is requested function removeAsset( address _asset, uint _assetIndex ) external auth { require(assetInformation[_asset].exists); require(registeredAssets[_assetIndex] == _asset); delete assetInformation[_asset]; delete registeredAssets[_assetIndex]; for (uint i = _assetIndex; i < registeredAssets.length-1; i++) { registeredAssets[i] = registeredAssets[i+1]; } registeredAssets.pop(); emit AssetRemoval(_asset); } /// @notice Deletes an existing entry /// @dev Owner can delete an existing entry /// @param _adapter address of the adapter of the exchange that is to be removed /// @param _adapterIndex index of the exchange in array function removeExchangeAdapter( address _adapter, uint _adapterIndex ) external auth { require(exchangeInformation[_adapter].exists, "Exchange with adapter doesn't exist"); require(registeredExchangeAdapters[_adapterIndex] == _adapter, "Incorrect adapter index"); delete exchangeInformation[_adapter]; delete registeredExchangeAdapters[_adapterIndex]; for (uint i = _adapterIndex; i < registeredExchangeAdapters.length-1; i++) { registeredExchangeAdapters[i] = registeredExchangeAdapters[i+1]; } registeredExchangeAdapters.pop(); emit ExchangeAdapterRemoval(_adapter); } function registerFees(address[] calldata _fees) external auth { for (uint i; i < _fees.length; i++) { isFeeRegistered[_fees[i]] = true; } } function deregisterFees(address[] calldata _fees) external auth { for (uint i; i < _fees.length; i++) { delete isFeeRegistered[_fees[i]]; } } // PUBLIC VIEW METHODS // get asset specific information function getName(address _asset) external view returns (string memory) { return assetInformation[_asset].name; } function getSymbol(address _asset) external view returns (string memory) { return assetInformation[_asset].symbol; } function getDecimals(address _asset) external view returns (uint) { return assetInformation[_asset].decimals; } function getReserveMin(address _asset) external view returns (uint) { return assetInformation[_asset].reserveMin; } function assetIsRegistered(address _asset) external view returns (bool) { return assetInformation[_asset].exists; } function getRegisteredAssets() external view returns (address[] memory) { return registeredAssets; } function assetMethodIsAllowed(address _asset, bytes4 _sig) external view returns (bool) { bytes4[] memory signatures = assetInformation[_asset].sigs; for (uint i = 0; i < signatures.length; i++) { if (signatures[i] == _sig) { return true; } } return false; } // get exchange-specific information function exchangeAdapterIsRegistered(address _adapter) external view returns (bool) { return exchangeInformation[_adapter].exists; } function getRegisteredExchangeAdapters() external view returns (address[] memory) { return registeredExchangeAdapters; } function getExchangeInformation(address _adapter) public view returns (address, bool) { Exchange memory exchange = exchangeInformation[_adapter]; return ( exchange.exchangeAddress, exchange.takesCustody ); } function exchangeForAdapter(address _adapter) external view returns (address) { Exchange memory exchange = exchangeInformation[_adapter]; return exchange.exchangeAddress; } function getAdapterFunctionSignatures(address _adapter) public view returns (bytes4[] memory) { return exchangeInformation[_adapter].sigs; } function adapterMethodIsAllowed( address _adapter, bytes4 _sig ) external view returns (bool) { bytes4[] memory signatures = exchangeInformation[_adapter].sigs; for (uint i = 0; i < signatures.length; i++) { if (signatures[i] == _sig) { return true; } } return false; } // get version and fund information function getRegisteredVersions() external view returns (address[] memory) { return registeredVersions; } function isFund(address _who) external view returns (bool) { if (fundsToVersions[_who] != address(0)) { return true; // directly from a hub } else { Hub hub = Hub(Spoke(_who).hub()); require( hub.isSpoke(_who), "Call from either a spoke or hub" ); return fundsToVersions[address(hub)] != address(0); } } function isFundFactory(address _who) external view returns (bool) { return versionInformation[_who].exists; } }
pragma solidity 0.6.1; /** * @title SafeMath * @dev Math operations with safety checks that revert on error */ library SafeMath { /** * @dev Multiplies two numbers, reverts on overflow. */ function mul(uint256 _a, uint256 _b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 if (_a == 0) { return 0; } uint256 c = _a * _b; require(c / _a == _b); return c; } /** * @dev Integer division of two numbers truncating the quotient, reverts on division by zero. */ function div(uint256 _a, uint256 _b) internal pure returns (uint256) { require(_b > 0); // Solidity only automatically asserts when dividing by 0 uint256 c = _a / _b; // assert(_a == _b * c + _a % _b); // There is no case in which this doesn't hold return c; } /** * @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend). */ function sub(uint256 _a, uint256 _b) internal pure returns (uint256) { require(_b <= _a); uint256 c = _a - _b; return c; } /** * @dev Adds two numbers, reverts on overflow. */ function add(uint256 _a, uint256 _b) internal pure returns (uint256) { uint256 c = _a + _b; require(c >= _a); return c; } /** * @dev Divides two numbers and returns the remainder (unsigned integer modulo), * reverts when dividing by zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b != 0); return a % b; } }
/// @notice Retrieved from DappHub (https://git.io/fpwMi) pragma solidity 0.6.1; import "./DSAuth.sol"; contract DSGuardEvents { event LogPermit( bytes32 indexed src, bytes32 indexed dst, bytes32 indexed sig ); event LogForbid( bytes32 indexed src, bytes32 indexed dst, bytes32 indexed sig ); } contract DSGuard is DSAuth, DSAuthority, DSGuardEvents { bytes32 constant public ANY = bytes32(uint(-1)); mapping (bytes32 => mapping (bytes32 => mapping (bytes32 => bool))) acl; function canCall( address src_, address dst_, bytes4 sig ) public view override returns (bool) { bytes32 src = bytes32(bytes20(src_)); bytes32 dst = bytes32(bytes20(dst_)); return acl[src][dst][sig] || acl[src][dst][ANY] || acl[src][ANY][sig] || acl[src][ANY][ANY] || acl[ANY][dst][sig] || acl[ANY][dst][ANY] || acl[ANY][ANY][sig] || acl[ANY][ANY][ANY]; } function permit(bytes32 src, bytes32 dst, bytes32 sig) public auth { acl[src][dst][sig] = true; emit LogPermit(src, dst, sig); } function forbid(bytes32 src, bytes32 dst, bytes32 sig) public auth { acl[src][dst][sig] = false; emit LogForbid(src, dst, sig); } function permit(address src, address dst, bytes32 sig) public { permit(bytes32(bytes20(src)), bytes32(bytes20(dst)), sig); } function forbid(address src, address dst, bytes32 sig) public { forbid(bytes32(bytes20(src)), bytes32(bytes20(dst)), sig); } } contract DSGuardFactory { mapping (address => bool) public isGuard; function newGuard() public returns (DSGuard guard) { guard = new DSGuard(); guard.setOwner(msg.sender); isGuard[address(guard)] = true; } }
pragma solidity 0.6.1; /// @dev Exposes "feeAmount", which maps fund state and fee state to uint /// @dev Notice that "feeAmount" *may* change contract state /// @dev Also exposes "updateState", which changes fee's internal state interface IFee { function initializeForUser(uint feeRate, uint feePeriod, address denominationAsset) external; function feeAmount() external returns (uint); function updateState() external; /// @notice Used to enforce a convention function identifier() external view returns (uint); }
pragma solidity 0.6.1; interface IFeeManagerFactory { function createInstance( address _hub, address _denominationAsset, address[] calldata _fees, uint[] calldata _feeRates, uint[] calldata _feePeriods, address _registry ) external returns (address); }
{ "remappings": [ "ds-test/=lib/forge-std/lib/ds-test/src/", "forge-std/=lib/forge-std/src/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs" }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "evmVersion": "istanbul", "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_hub","type":"address"},{"internalType":"address[]","name":"_defaultAssets","type":"address[]"},{"internalType":"address","name":"_registry","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"payer","type":"address"},{"indexed":false,"internalType":"uint256","name":"totalAmguPaidInEth","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amguChargableGas","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"incentivePaid","type":"uint256"}],"name":"AmguPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"requestOwner","type":"address"}],"name":"CancelRequest","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"assets","type":"address[]"}],"name":"DisableInvestment","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"asset","type":"address[]"}],"name":"EnableInvestment","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"requestOwner","type":"address"},{"indexed":true,"internalType":"address","name":"investmentAsset","type":"address"},{"indexed":false,"internalType":"uint256","name":"requestedShares","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"investmentAmount","type":"uint256"}],"name":"InvestmentRequest","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"authority","type":"address"}],"name":"LogSetAuthority","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"}],"name":"LogSetOwner","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"redeemer","type":"address"},{"indexed":false,"internalType":"address[]","name":"assets","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"assetQuantities","type":"uint256[]"},{"indexed":false,"internalType":"uint256","name":"redeemedShares","type":"uint256"}],"name":"Redemption","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"requestOwner","type":"address"},{"indexed":true,"internalType":"address","name":"executor","type":"address"},{"indexed":true,"internalType":"address","name":"investmentAsset","type":"address"},{"indexed":false,"internalType":"uint256","name":"investmentAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"requestedShares","type":"uint256"}],"name":"RequestExecution","type":"event"},{"inputs":[],"name":"REQUEST_LIFESPAN","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SHARES_DECIMALS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"authority","outputs":[{"internalType":"contract DSAuthority","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cancelRequest","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"requestOwner","type":"address"}],"name":"cancelRequestFor","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_assets","type":"address[]"}],"name":"disableInvestment","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_assets","type":"address[]"}],"name":"enableInvestment","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"engine","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"requestOwner","type":"address"}],"name":"executeRequestFor","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"getHistoricalInvestors","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shareQuantity","type":"uint256"}],"name":"getOwedPerformanceFees","outputs":[{"internalType":"uint256","name":"remainingShareQuantity","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_who","type":"address"}],"name":"hasExpiredRequest","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"hasInvested","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_who","type":"address"}],"name":"hasRequest","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_who","type":"address"}],"name":"hasValidRequest","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"historicalInvestors","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hub","outputs":[{"internalType":"contract Hub","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[11]","name":"_spokes","type":"address[11]"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"initialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"investAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mlnToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"priceSource","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"redeem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"shareQuantity","type":"uint256"}],"name":"redeemQuantity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"shareQuantity","type":"uint256"},{"internalType":"address[]","name":"requestedAssets","type":"address[]"}],"name":"redeemWithConstraints","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"registry","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"requestedShares","type":"uint256"},{"internalType":"uint256","name":"investmentAmount","type":"uint256"},{"internalType":"address","name":"investmentAsset","type":"address"}],"name":"requestInvestment","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"requests","outputs":[{"internalType":"address","name":"investmentAsset","type":"address"},{"internalType":"uint256","name":"investmentAmount","type":"uint256"},{"internalType":"uint256","name":"requestedShares","type":"uint256"},{"internalType":"uint256","name":"timestamp","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"routes","outputs":[{"internalType":"address","name":"accounting","type":"address"},{"internalType":"address","name":"feeManager","type":"address"},{"internalType":"address","name":"participation","type":"address"},{"internalType":"address","name":"policyManager","type":"address"},{"internalType":"address","name":"shares","type":"address"},{"internalType":"address","name":"trading","type":"address"},{"internalType":"address","name":"vault","type":"address"},{"internalType":"address","name":"registry","type":"address"},{"internalType":"address","name":"version","type":"address"},{"internalType":"address","name":"engine","type":"address"},{"internalType":"address","name":"mlnToken","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract DSAuthority","name":"authority_","type":"address"}],"name":"setAuthority","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner_","type":"address"}],"name":"setOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Deployed Bytecode
0x6080604052600436106101f25760003560e01c8063643466af1161010d578063b1ffd471116100a0578063c9d4623f1161006f578063c9d4623f146107a6578063e216ea2b146107bb578063ec622892146107ee578063edb9a5c014610869578063f16ab6dc1461089c576101f9565b8063b1ffd471146106d0578063be040fb014610752578063bec6146214610767578063bf7e214f14610791576101f9565b80637baf5929116100dc5780637baf592914610678578063851b16f51461069e5780638a471df9146106a65780638da5cb5b146106bb576101f9565b8063643466af1461056857806374adad1d146105cd5780637a9e5e4b146106305780637b10399914610663576101f9565b806344ed98dd1161018557806354c3b8c51161015457806354c3b8c51461043957806354fd4d501461046c5780635810a54c146104815780635d58287014610536576101f9565b806344ed98dd146103a0578063474e19f2146103dc57806349837b5e146103f15780634a248e2714610406576101f9565b806320531bc9116101c157806320531bc9146102ac578063212f6066146102dd578063365a86fc14610358578063429f41a71461036d576101f9565b80630b797141146101fe5780630d2485b11461022a57806313af403514610250578063158ef93e14610283576101f9565b366101f957005b600080fd5b34801561020a57600080fd5b506102286004803603602081101561022157600080fd5b50356108c6565b005b6102286004803603602081101561024057600080fd5b50356001600160a01b03166109e2565b34801561025c57600080fd5b506102286004803603602081101561027357600080fd5b50356001600160a01b0316610d94565b34801561028f57600080fd5b50610298610e42565b604080519115158252519081900360200190f35b3480156102b857600080fd5b506102c1610e4b565b604080516001600160a01b039092168252519081900360200190f35b3480156102e957600080fd5b506102286004803603602081101561030057600080fd5b810190602081018135600160201b81111561031a57600080fd5b82018360208201111561032c57600080fd5b803590602001918460208302840111600160201b8311171561034d57600080fd5b509092509050610e5a565b34801561036457600080fd5b506102c1610ef4565b34801561037957600080fd5b506102986004803603602081101561039057600080fd5b50356001600160a01b0316610f03565b3480156103ac57600080fd5b506103ca600480360360208110156103c357600080fd5b5035611087565b60408051918252519081900360200190f35b3480156103e857600080fd5b506103ca611199565b3480156103fd57600080fd5b506103ca61119e565b34801561041257600080fd5b506102986004803603602081101561042957600080fd5b50356001600160a01b03166111a5565b34801561044557600080fd5b506102986004803603602081101561045c57600080fd5b50356001600160a01b03166111d6565b34801561047857600080fd5b506102c16111eb565b34801561048d57600080fd5b50610228600480360360408110156104a457600080fd5b81359190810190604081016020820135600160201b8111156104c557600080fd5b8201836020820111156104d757600080fd5b803590602001918460208302840111600160201b831117156104f857600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295506111fa945050505050565b6102286004803603606081101561054c57600080fd5b50803590602081013590604001356001600160a01b0316611b9a565b34801561057457600080fd5b5061057d6123d1565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156105b95781810151838201526020016105a1565b505050509050019250505060405180910390f35b3480156105d957600080fd5b50610600600480360360208110156105f057600080fd5b50356001600160a01b0316612433565b604080516001600160a01b0390951685526020850193909352838301919091526060830152519081900360800190f35b34801561063c57600080fd5b506102286004803603602081101561065357600080fd5b50356001600160a01b0316612464565b34801561066f57600080fd5b506102c161250e565b6102286004803603602081101561068e57600080fd5b50356001600160a01b0316612518565b610228612aaa565b3480156106b257600080fd5b506102c1612e50565b3480156106c757600080fd5b506102c1612e5a565b3480156106dc57600080fd5b506106e5612e69565b604080516001600160a01b039c8d1681529a8c1660208c0152988b168a8a0152968a1660608a0152948916608089015292881660a088015290871660c0870152861660e0860152851661010085015284166101208401529092166101408201529051908190036101600190f35b34801561075e57600080fd5b50610228612ebe565b34801561077357600080fd5b50610228600480360361016081101561078b57600080fd5b50612f43565b34801561079d57600080fd5b506102c161326f565b3480156107b257600080fd5b506102c161327e565b3480156107c757600080fd5b50610298600480360360208110156107de57600080fd5b50356001600160a01b0316613288565b3480156107fa57600080fd5b506102286004803603602081101561081157600080fd5b810190602081018135600160201b81111561082b57600080fd5b82018360208201111561083d57600080fd5b803590602001918460208302840111600160201b8311171561085e57600080fd5b5090925090506132a8565b34801561087557600080fd5b506102986004803603602081101561088c57600080fd5b50356001600160a01b03166133c4565b3480156108a857600080fd5b506102c1600480360360208110156108bf57600080fd5b50356133d9565b60035460408051630a616f2560e21b815290516060926001600160a01b031691632985bc94916004808301926000929190829003018186803b15801561090b57600080fd5b505afa15801561091f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561094857600080fd5b8101908080516040519392919084600160201b82111561096757600080fd5b90830190602082018581111561097c57600080fd5b82518660208202830111600160201b8211171561099857600080fd5b82525081516020918201928201910280838360005b838110156109c55781810151838201526020016109ad565b5050505090500160405250505090506109de82826111fa565b5050565b6000805a90506109f183613400565b60005a90506000610a0061327e565b6001600160a01b031663709bb5676040518163ffffffff1660e01b815260040160206040518083038186803b158015610a3857600080fd5b505afa158015610a4c573d6000803e3d6000fd5b505050506040513d6020811015610a6257600080fd5b505190506000610a7b82610a768686613703565b613759565b90506000610a8761250e565b6001600160a01b03166374d32ad46040518163ffffffff1660e01b815260040160206040518083038186803b158015610abf57600080fd5b505afa158015610ad3573d6000803e3d6000fd5b505050506040513d6020811015610ae957600080fd5b505190506000610af7610e4b565b6001600160a01b0316637e3bfc2f84610b0e612e50565b856040518463ffffffff1660e01b815260040180848152602001836001600160a01b03166001600160a01b03168152602001826001600160a01b03166001600160a01b03168152602001935050505060206040518083038186803b158015610b7557600080fd5b505afa158015610b89573d6000803e3d6000fd5b505050506040513d6020811015610b9f57600080fd5b5051905060008715610c1e57610bb361250e565b6001600160a01b0316631d4632ac6040518163ffffffff1660e01b815260040160206040518083038186803b158015610beb57600080fd5b505afa158015610bff573d6000803e3d6000fd5b505050506040513d6020811015610c1557600080fd5b50519050610c22565b5060005b610c2c82826137bc565b341015610c6a5760405162461bcd60e51b81526004018080602001828103825260218152602001806140366021913960400191505060405180910390fd5b610c7261327e565b6001600160a01b0316635ce1fb54836040518263ffffffff1660e01b81526004016000604051808303818588803b158015610cac57600080fd5b505af1158015610cc0573d6000803e3d6000fd5b5050505050336001600160a01b03166108fc610ce5610cdf3486613703565b84613703565b6040518115909202916000818181858888f19350505050610d3d576040805162461bcd60e51b815260206004820152600d60248201526c1499599d5b990819985a5b1959609a1b604482015290519081900360640190fd5b337f0fa722789511f8feef9c02f613ad3ad10699034c1725894b9e7040552af4ffb983610d6a8a8a613703565b604080519283526020830191909152818101859052519081900360600190a2505050505050505050565b610daa336000356001600160e01b03191661380b565b610df2576040805162461bcd60e51b8152602060048201526014602482015273191ccb585d5d1a0b5d5b985d5d1a1bdc9a5e995960621b604482015290519081900360640190fd5b600180546001600160a01b0319166001600160a01b0383811691909117918290556040519116907fce241d7ca1f669fee44b6fc00b8eba2df3bb514eed0f6f668f8f89096e81ed9490600090a250565b600e5460ff1681565b6000610e556138f2565b905090565b610e70336000356001600160e01b03191661380b565b610eb8576040805162461bcd60e51b8152602060048201526014602482015273191ccb585d5d1a0b5d5b985d5d1a1bdc9a5e995960621b604482015290519081900360640190fd5b6109de82828080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061396892505050565b6002546001600160a01b031681565b600080610f0e610e4b565b90506000816001600160a01b0316634c89867f6040518163ffffffff1660e01b815260040160206040518083038186803b158015610f4b57600080fd5b505afa158015610f5f573d6000803e3d6000fd5b505050506040513d6020811015610f7557600080fd5b50516001600160a01b0385166000908152600f6020526040902060030154108061100d5750600754604080516318160ddd60e01b815290516001600160a01b03909216916318160ddd91600481810192602092909190829003018186803b158015610fdf57600080fd5b505afa158015610ff3573d6000803e3d6000fd5b505050506040513d602081101561100957600080fd5b5051155b905061101884613288565b80156110215750805b80156110335750611031846111a5565b155b801561105957506001600160a01b0384166000908152600f602052604090206001015415155b801561107f57506001600160a01b0384166000908152600f602052604090206002015415155b949350505050565b60075460048054604080516335ff1bb760e01b815290516000946001600160a01b03908116948694909116926335ff1bb7928183019260209282900301818787803b1580156110d557600080fd5b505af11580156110e9573d6000803e3d6000fd5b505050506040513d60208110156110ff57600080fd5b5051604080516318160ddd60e01b8152905191925060009161117e916001600160a01b038616916318160ddd91600480820192602092909190829003018186803b15801561114c57600080fd5b505afa158015611160573d6000803e3d6000fd5b505050506040513d602081101561117657600080fd5b5051836137bc565b6111888387613759565b8161118f57fe5b0495945050505050565b601281565b6201518081565b6001600160a01b0381166000908152600f60205260408120600301546111ce90620151806137bc565b421192915050565b60106020526000908152604090205460ff1681565b600b546001600160a01b031690565b600754604080516370a0823160e01b815233600482015290516001600160a01b0390921691849183916370a0823191602480820192602092909190829003018186803b15801561124957600080fd5b505afa15801561125d573d6000803e3d6000fd5b505050506040513d602081101561127357600080fd5b5051108015906112f65750604080516370a0823160e01b815233600482015290516000916001600160a01b038416916370a0823191602480820192602092909190829003018186803b1580156112c857600080fd5b505afa1580156112dc573d6000803e3d6000fd5b505050506040513d60208110156112f257600080fd5b5051115b6113315760405162461bcd60e51b8152600401808060200182810382526035815260200180613fb16035913960400191505060405180910390fd5b600061133b610e4b565b6001600160a01b03166380971a36846040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019060200280838360005b83811015611399578181015183820152602001611381565b505050509050019250505060206040518083038186803b1580156113bc57600080fd5b505afa1580156113d0573d6000803e3d6000fd5b505050506040513d60208110156113e657600080fd5b505180156114765750600260009054906101000a90046001600160a01b03166001600160a01b031663481c6a756040518163ffffffff1660e01b815260040160206040518083038186803b15801561143d57600080fd5b505afa158015611451573d6000803e3d6000fd5b505050506040513d602081101561146757600080fd5b50516001600160a01b03163314155b15611638576004805460408051631bb7381160e31b815290516001600160a01b039092169263ddb9c08892828201926000929082900301818387803b1580156114be57600080fd5b505af11580156114d2573d6000803e3d6000fd5b505050506114df84611087565b604080516366bde28b60e11b81523360048201526024810183905290519192506001600160a01b0384169163cd7bc5169160448082019260009290919082900301818387803b15801561153157600080fd5b505af1158015611545573d6000803e3d6000fd5b50505050816001600160a01b0316631d48946c600260009054906101000a90046001600160a01b03166001600160a01b031663481c6a756040518163ffffffff1660e01b815260040160206040518083038186803b1580156115a657600080fd5b505afa1580156115ba573d6000803e3d6000fd5b505050506040513d60208110156115d057600080fd5b5051604080516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820185905251604480830192600092919082900301818387803b15801561161f57600080fd5b505af1158015611633573d6000803e3d6000fd5b505050505b60006116448583613703565b9050600060608551604051908082528060200260200182016040528015611675578160200160208202803883390190505b509050606086516040519080825280602002602001820160405280156116a5578160200160208202803883390190505b506003549091506001600160a01b031660005b885181101561195c578881815181106116cd57fe5b60200260200101519450816001600160a01b0316630e7a2d4e866040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561172d57600080fd5b505afa158015611741573d6000803e3d6000fd5b505050506040513d602081101561175757600080fd5b50516117945760405162461bcd60e51b8152600401808060200182810382526021815260200180613f6f6021913960400191505060405180910390fd5b60005b8351811015611822578381815181106117ac57fe5b60200260200101516001600160a01b0316866001600160a01b0316141561181a576040805162461bcd60e51b815260206004820152601f60248201527f41737365742063616e206f6e6c792062652072656465656d6564206f6e636500604482015290519081900360640190fd5b600101611797565b508483828151811061183057fe5b6001600160a01b039283166020918202929092018101919091526040805163ca334fe560e01b81528884166004820152905160009386169263ca334fe5926024808201939182900301818787803b15801561188a57600080fd5b505af115801561189e573d6000803e3d6000fd5b505050506040513d60208110156118b457600080fd5b50519050806118c35750611954565b886001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156118fc57600080fd5b505afa158015611910573d6000803e3d6000fd5b505050506040513d602081101561192657600080fd5b50516119328289613759565b8161193957fe5b0485838151811061194657fe5b602002602001018181525050505b6001016116b8565b50604080516366bde28b60e11b81523360048201526024810187905290516001600160a01b0389169163cd7bc51691604480830192600092919082900301818387803b1580156119ab57600080fd5b505af11580156119bf573d6000803e3d6000fd5b506000925050505b8851811015611ac1578881815181106119dc57fe5b602002602001015194508381815181106119f257fe5b602002602001015160001415611a0757611ab9565b60095484516001600160a01b039091169063f3fef3a3908790879085908110611a2c57fe5b60200260200101516040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015611a8357600080fd5b505af1158015611a97573d6000803e3d6000fd5b50505050611ab98533868481518110611aac57fe5b6020026020010151613b1e565b6001016119c7565b50336001600160a01b03167f976b5f495b9d6400bbe35e173a78de5e77ffd728e55e900f45a495dec4143e17898588604051808060200180602001848152602001838103835286818151815260200191508051906020019060200280838360005b83811015611b3a578181015183820152602001611b22565b50505050905001838103825285818151815260200191508051906020019060200280838360005b83811015611b79578181015183820152602001611b61565b505050509050019550505050505060405180910390a2505050505050505050565b600260009054906101000a90046001600160a01b03166001600160a01b031663ff9475256040518163ffffffff1660e01b815260040160206040518083038186803b158015611be857600080fd5b505afa158015611bfc573d6000803e3d6000fd5b505050506040513d6020811015611c1257600080fd5b505115611c59576040805162461bcd60e51b815260206004820152601060248201526f243ab11034b99039b43aba103237bbb760811b604482015290519081900360640190fd5b600160005a600e5490915060ff16611cb8576040805162461bcd60e51b815260206004820152601d60248201527f436f6d706f6e656e74206e6f742079657420696e697469616c697a6564000000604482015290519081900360640190fd5b6006546040805160a08082018352338252600060208084018290528385018290526001600160a01b038981166060808701919091526080860184905286519081018752838152918201839052818601839052945163da6670d360e01b81526001600160e01b031983351660048201818152969097169663da6670d3969095949293929091602401908590808383875b83811015611d5f578181015183820152602001611d47565b5050505090500183600360200280838360005b83811015611d8a578181015183820152602001611d72565b50505050905001828152602001945050505050600060405180830381600087803b158015611db757600080fd5b505af1158015611dcb573d6000803e3d6000fd5b505050506001600160a01b03831660009081526010602052604090205460ff16611e265760405162461bcd60e51b81526004018080602001828103825260248152602001806140576024913960400191505060405180910390fd5b611e3283333087613ceb565b336000908152600f602052604090206003015415611e815760405162461bcd60e51b8152600401808060200182810382526024815260200180613f4b6024913960400191505060405180910390fd5b60408051608080820183526001600160a01b0386811680845260208085018a81528587018c8152426060808901918252336000818152600f87528b81209a518b546001600160a01b031916908a16178b55945160018b0155925160028a01559051600390980197909755600654885160a08082018b52928152808501849052808a018490528089019590955295840182905287519687018852818752918601819052858701819052955163185f31cf60e31b815286356001600160e01b03191660048201818152959094169663c2f98e7896949593949390929091602401908590808383875b83811015611f7f578181015183820152602001611f67565b5050505090500183600360200280838360005b83811015611faa578181015183820152602001611f92565b50505050905001828152602001945050505050600060405180830381600087803b158015611fd757600080fd5b505af1158015611feb573d6000803e3d6000fd5b5050604080518881526020810188905281516001600160a01b03881694503393507f7ac4e9fa94c85b700a3c05a368f0cbc8503fba59158d3e01cc96f608c82bb202929181900390910190a360005a9050600061204661327e565b6001600160a01b031663709bb5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561207e57600080fd5b505afa158015612092573d6000803e3d6000fd5b505050506040513d60208110156120a857600080fd5b5051905060006120bc82610a768686613703565b905060006120c861250e565b6001600160a01b03166374d32ad46040518163ffffffff1660e01b815260040160206040518083038186803b15801561210057600080fd5b505afa158015612114573d6000803e3d6000fd5b505050506040513d602081101561212a57600080fd5b505190506000612138610e4b565b6001600160a01b0316637e3bfc2f8461214f612e50565b856040518463ffffffff1660e01b815260040180848152602001836001600160a01b03166001600160a01b03168152602001826001600160a01b03166001600160a01b03168152602001935050505060206040518083038186803b1580156121b657600080fd5b505afa1580156121ca573d6000803e3d6000fd5b505050506040513d60208110156121e057600080fd5b505190506000871561225f576121f461250e565b6001600160a01b0316631d4632ac6040518163ffffffff1660e01b815260040160206040518083038186803b15801561222c57600080fd5b505afa158015612240573d6000803e3d6000fd5b505050506040513d602081101561225657600080fd5b50519050612263565b5060005b61226d82826137bc565b3410156122ab5760405162461bcd60e51b81526004018080602001828103825260218152602001806140366021913960400191505060405180910390fd5b6122b361327e565b6001600160a01b0316635ce1fb54836040518263ffffffff1660e01b81526004016000604051808303818588803b1580156122ed57600080fd5b505af1158015612301573d6000803e3d6000fd5b5050505050336001600160a01b03166108fc612320610cdf3486613703565b6040518115909202916000818181858888f19350505050612378576040805162461bcd60e51b815260206004820152600d60248201526c1499599d5b990819985a5b1959609a1b604482015290519081900360640190fd5b337f0fa722789511f8feef9c02f613ad3ad10699034c1725894b9e7040552af4ffb9836123a58a8a613703565b604080519283526020830191909152818101859052519081900360600190a25050505050505050505050565b6060601280548060200260200160405190810160405280929190818152602001828054801561242957602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161240b575b5050505050905090565b600f6020526000908152604090208054600182015460028301546003909301546001600160a01b0390921692909184565b61247a336000356001600160e01b03191661380b565b6124c2576040805162461bcd60e51b8152602060048201526014602482015273191ccb585d5d1a0b5d5b985d5d1a1bdc9a5e995960621b604482015290519081900360640190fd5b600080546001600160a01b0319166001600160a01b03838116919091178083556040519116917f1abebea81bfa2637f28358c371278fb15ede7ea8dd28d2e03b112ff6d936ada491a250565b6000610e55613ec1565b600260009054906101000a90046001600160a01b03166001600160a01b031663ff9475256040518163ffffffff1660e01b815260040160206040518083038186803b15801561256657600080fd5b505afa15801561257a573d6000803e3d6000fd5b505050506040513d602081101561259057600080fd5b5051156125d7576040805162461bcd60e51b815260206004820152601060248201526f243ab11034b99039b43aba103237bbb760811b604482015290519081900360640190fd5b6000805a90506125e5613eee565b506001600160a01b038084166000908152600f602090815260409182902082516080810184528154909416845260018101549184019190915260028101549183019190915260030154606082015261263c84610f03565b6126775760405162461bcd60e51b81526004018080602001828103825260218152602001806140156021913960400191505060405180910390fd5b6004805460408051631bb7381160e31b815290516001600160a01b039092169263ddb9c08892828201926000929082900301818387803b1580156126ba57600080fd5b505af11580156126ce573d6000803e3d6000fd5b50506003546040808501518551825163896aad5360e01b815260048101929092526001600160a01b03908116602483015291516000955091909216925063896aad539160448082019260209290919082900301818787803b15801561273257600080fd5b505af1158015612746573d6000803e3d6000fd5b505050506040513d602081101561275c57600080fd5b505160208301519091508111156127ba576040805162461bcd60e51b815260206004820152601760248201527f496e76657374656420616d6f756e7420746f6f206c6f77000000000000000000604482015290519081900360640190fd5b81516009546127d391906001600160a01b031683613b1e565b60006127e3836020015183613703565b905080156127f85782516127f8908783613b1e565b600a54604080516307518cab60e21b8152905133926108fc926001600160a01b0390911691631d4632ac91600480820192602092909190829003018186803b15801561284357600080fd5b505afa158015612857573d6000803e3d6000fd5b505050506040513d602081101561286d57600080fd5b50516040518115909202916000818181858888f19350505050158015612897573d6000803e3d6000fd5b506007546040808501518151630752251b60e21b81526001600160a01b038a8116600483015260248201929092529151921691631d48946c9160448082019260009290919082900301818387803b1580156128f157600080fd5b505af1158015612905573d6000803e3d6000fd5b50506003548551604080516301ebef9d60e21b81526001600160a01b03928316600482015290519190921693506307afbe749250602480830192600092919082900301818387803b15801561295957600080fd5b505af115801561296d573d6000803e3d6000fd5b505050506001600160a01b03861660009081526011602052604090205460ff166129f7576001600160a01b0386166000818152601160205260408120805460ff191660019081179091556012805491820181559091527fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec34440180546001600160a01b03191690911790555b82600001516001600160a01b0316336001600160a01b0316876001600160a01b03167fd826cdb072fceaa49209a7f9dc6283914ae87fb72f26cc328c67f8b54599957b86602001518760400151604051808381526020018281526020019250505060405180910390a45050506001600160a01b0383166000908152600f6020526040812080546001600160a01b031916815560018101829055600281018290556003018190555a90506000610a0061327e565b6000805a9050612ab933613400565b60005a90506000612ac861327e565b6001600160a01b031663709bb5676040518163ffffffff1660e01b815260040160206040518083038186803b158015612b0057600080fd5b505afa158015612b14573d6000803e3d6000fd5b505050506040513d6020811015612b2a57600080fd5b505190506000612b3e82610a768686613703565b90506000612b4a61250e565b6001600160a01b03166374d32ad46040518163ffffffff1660e01b815260040160206040518083038186803b158015612b8257600080fd5b505afa158015612b96573d6000803e3d6000fd5b505050506040513d6020811015612bac57600080fd5b505190506000612bba610e4b565b6001600160a01b0316637e3bfc2f84612bd1612e50565b856040518463ffffffff1660e01b815260040180848152602001836001600160a01b03166001600160a01b03168152602001826001600160a01b03166001600160a01b03168152602001935050505060206040518083038186803b158015612c3857600080fd5b505afa158015612c4c573d6000803e3d6000fd5b505050506040513d6020811015612c6257600080fd5b5051905060008715612ce157612c7661250e565b6001600160a01b0316631d4632ac6040518163ffffffff1660e01b815260040160206040518083038186803b158015612cae57600080fd5b505afa158015612cc2573d6000803e3d6000fd5b505050506040513d6020811015612cd857600080fd5b50519050612ce5565b5060005b612cef82826137bc565b341015612d2d5760405162461bcd60e51b81526004018080602001828103825260218152602001806140366021913960400191505060405180910390fd5b612d3561327e565b6001600160a01b0316635ce1fb54836040518263ffffffff1660e01b81526004016000604051808303818588803b158015612d6f57600080fd5b505af1158015612d83573d6000803e3d6000fd5b5050505050336001600160a01b03166108fc612da2610cdf3486613703565b6040518115909202916000818181858888f19350505050612dfa576040805162461bcd60e51b815260206004820152600d60248201526c1499599d5b990819985a5b1959609a1b604482015290519081900360640190fd5b337f0fa722789511f8feef9c02f613ad3ad10699034c1725894b9e7040552af4ffb983612e278a8a613703565b604080519283526020830191909152818101859052519081900360600190a25050505050505050565b6000610e55613ed0565b6001546001600160a01b031681565b600354600454600554600654600754600854600954600a54600b54600c54600d546001600160a01b039a8b169a998a16999889169897881697968716969586169594851694938416939283169291821691168b565b600754604080516370a0823160e01b815233600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b158015612f0957600080fd5b505afa158015612f1d573d6000803e3d6000fd5b505050506040513d6020811015612f3357600080fd5b50519050612f40816108c6565b50565b612f59336000356001600160e01b03191661380b565b612fa1576040805162461bcd60e51b8152602060048201526014602482015273191ccb585d5d1a0b5d5b985d5d1a1bdc9a5e995960621b604482015290519081900360640190fd5b6002546001600160a01b03163314612fb857600080fd5b600e5460ff1615613006576040805162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481a5b9a5d1a585b1a5e9959606a1b604482015290519081900360640190fd5b60408051610160810182526001600160a01b038335811682526020808501358216908301528383013516918101919091526060810182600360200201356001600160a01b03166001600160a01b03168152602001826004600b811061306757fe5b60200201356001600160a01b03166001600160a01b03168152602001826005600b811061309057fe5b60200201356001600160a01b03166001600160a01b03168152602001826006600b81106130b957fe5b60200201356001600160a01b03166001600160a01b03168152602001826007600b81106130e257fe5b60200201356001600160a01b03166001600160a01b03168152602001826008600b811061310b57fe5b60200201356001600160a01b03166001600160a01b03168152602001826009600b811061313457fe5b60200201356001600160a01b03166001600160a01b0316815260200182600a600b811061315d57fe5b602090810291909101356001600160a01b039081169092528251600380546001600160a01b03199081169285169290921790559083015160048054831691841691909117905560408301516005805483169184169190911790556060830151600680548316918416919091179055608083015160078054831691841691909117905560a083015160088054831691841691909117905560c083015160098054831691841691909117905560e0830151600a80548316918416919091179055610100830151600b80548316918416919091179055610120830151600c8054831691841691909117905561014090920151600d80549093169116179055600e805460ff19166001179055612f406000610d94565b6000546001600160a01b031681565b6000610e55613edf565b6001600160a01b03166000908152600f6020526040902060030154151590565b6132be336000356001600160e01b03191661380b565b613306576040805162461bcd60e51b8152602060048201526014602482015273191ccb585d5d1a0b5d5b985d5d1a1bdc9a5e995960621b604482015290519081900360640190fd5b60005b8181101561335c5760006010600085858581811061332357fe5b602090810292909201356001600160a01b0316835250810191909152604001600020805460ff1916911515919091179055600101613309565b507f3dc6367c991e43485e267da6f765655c7afd64b44b9414b04ff80de370cf5121828260405180806020018281038252848482818152602001925060200280828437600083820152604051601f909101601f19169092018290039550909350505050a15050565b60116020526000908152604090205460ff1681565b601281815481106133e657fe5b6000918252602090912001546001600160a01b0316905081565b61340981613288565b613451576040805162461bcd60e51b8152602060048201526014602482015273139bc81c995c5d595cdd081d1bc818d85b98d95b60621b604482015290519081900360640190fd5b600061345b610e4b565b9050613465613eee565b506001600160a01b038083166000908152600f6020908152604091829020825160808101845281548516808252600183015482850152600283015482860152600390920154606082015283516313533b5560e01b81526004810192909252925192938516926313533b5592602480840193919291829003018186803b1580156134ed57600080fd5b505afa158015613501573d6000803e3d6000fd5b505050506040513d602081101561351757600080fd5b505115806135295750613529836111a5565b806135aa5750600260009054906101000a90046001600160a01b03166001600160a01b031663ff9475256040518163ffffffff1660e01b815260040160206040518083038186803b15801561357d57600080fd5b505afa158015613591573d6000803e3d6000fd5b505050506040513d60208110156135a757600080fd5b50515b6135e55760405162461bcd60e51b8152600401808060200182810382526021815260200180613f906021913960400191505060405180910390fd5b80516020808301516001600160a01b038087166000908152600f8452604080822080546001600160a01b0319168155600181018390556002810183905560030191909155600a5481516307518cab60e21b81529151939433946108fc949290921692631d4632ac9260048083019392829003018186803b15801561366857600080fd5b505afa15801561367c573d6000803e3d6000fd5b505050506040513d602081101561369257600080fd5b50516040518115909202916000818181858888f193505050501580156136bc573d6000803e3d6000fd5b506136c8828683613b1e565b6040516001600160a01b038616907f8a46aebe3d6766257a923c4a998b5fd32d693bd7877df2e25ea7b7099310da2b90600090a25050505050565b80820382811115613753576040805162461bcd60e51b815260206004820152601560248201527464732d6d6174682d7375622d756e646572666c6f7760581b604482015290519081900360640190fd5b92915050565b60008115806137745750508082028282828161377157fe5b04145b613753576040805162461bcd60e51b815260206004820152601460248201527364732d6d6174682d6d756c2d6f766572666c6f7760601b604482015290519081900360640190fd5b80820182811015613753576040805162461bcd60e51b815260206004820152601460248201527364732d6d6174682d6164642d6f766572666c6f7760601b604482015290519081900360640190fd5b60006001600160a01b03831630141561382657506001613753565b6001546001600160a01b038481169116141561384457506001613753565b6000546001600160a01b031661385c57506000613753565b6000546040805163b700961360e01b81526001600160a01b0386811660048301523060248301526001600160e01b0319861660448301529151919092169163b7009613916064808301926020929190829003018186803b1580156138bf57600080fd5b505afa1580156138d3573d6000803e3d6000fd5b505050506040513d60208110156138e957600080fd5b50519050613753565b600254604080516320531bc960e01b815290516000926001600160a01b0316916320531bc9916004808301926020929190829003018186803b15801561393757600080fd5b505afa15801561394b573d6000803e3d6000fd5b505050506040513d602081101561396157600080fd5b5051905090565b60005b8151811015613aa557600a5482516001600160a01b0390911690631f8d99a99084908490811061399757fe5b60200260200101516040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156139e557600080fd5b505afa1580156139f9573d6000803e3d6000fd5b505050506040513d6020811015613a0f57600080fd5b5051613a59576040805162461bcd60e51b8152602060048201526014602482015273105cdcd95d081b9bdd081c9959da5cdd195c995960621b604482015290519081900360640190fd5b600160106000848481518110613a6b57fe5b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff191691151591909117905560010161396b565b507f144a61ed164a4708d46e9929ca93ac8226b76226e0ceb5182c6eaa4d9cdc3429816040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015613b08578181015183820152602001613af0565b505050509050019250505060405180910390a150565b6000836001600160a01b03166370a08231846040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015613b7657600080fd5b505afa158015613b8a573d6000803e3d6000fd5b505050506040513d6020811015613ba057600080fd5b50516040805163a9059cbb60e01b81526001600160a01b0386811660048301526024820186905291519293509086169163a9059cbb916044808201926020929091908290030181600087803b158015613bf857600080fd5b505af1158015613c0c573d6000803e3d6000fd5b505050506040513d6020811015613c2257600080fd5b5050604080516370a0823160e01b81526001600160a01b03858116600483015291516000928716916370a08231916024808301926020929190829003018186803b158015613c6f57600080fd5b505afa158015613c83573d6000803e3d6000fd5b505050506040513d6020811015613c9957600080fd5b5051905080613ca883856137bc565b14613ce45760405162461bcd60e51b815260040180806020018281038252602b815260200180613f20602b913960400191505060405180910390fd5b5050505050565b6000846001600160a01b03166370a08231846040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015613d4357600080fd5b505afa158015613d57573d6000803e3d6000fd5b505050506040513d6020811015613d6d57600080fd5b5051604080516323b872dd60e01b81526001600160a01b0387811660048301528681166024830152604482018690529151929350908716916323b872dd916064808201926020929091908290030181600087803b158015613dcd57600080fd5b505af1158015613de1573d6000803e3d6000fd5b505050506040513d6020811015613df757600080fd5b5050604080516370a0823160e01b81526001600160a01b03858116600483015291516000928816916370a08231916024808301926020929190829003018186803b158015613e4457600080fd5b505afa158015613e58573d6000803e3d6000fd5b505050506040513d6020811015613e6e57600080fd5b5051905080613e7d83856137bc565b14613eb95760405162461bcd60e51b815260040180806020018281038252602f815260200180613fe6602f913960400191505060405180910390fd5b505050505050565b600a546001600160a01b031690565b600d546001600160a01b031690565b600c546001600160a01b031690565b604051806080016040528060006001600160a01b03168152602001600081526020016000815260200160008152509056fe526563656976657220646964206e6f74207265636569766520746f6b656e7320696e207472616e736665724f6e6c79206f6e6520726571756573742063616e20657869737420617420612074696d65526571756573746564206173736574206e6f7420696e206173736574206c6973744e6f2063616e63656c6c6174696f6e20636f6e646974696f6e20776173206d657453656e64657220646f6573206e6f74206861766520656e6f7567682073686172657320746f2066756c66696c6c2072657175657374526563656976657220646964206e6f74207265636569766520746f6b656e7320696e207472616e7366657246726f6d4e6f2076616c6964207265717565737420666f7220746869732061646472657373496e737566666963656e7420414d475520616e642f6f7220696e63656e74697665496e766573746d656e74206e6f7420616c6c6f77656420696e2074686973206173736574a2646970667358221220c8c881c31bf73e6260fa333441b2a86f898fe182daeacbdee21155d2d6683c2d64736f6c63430006010033
Deployed Bytecode Sourcemap
483:12567:16:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9426:219;;8:9:-1;5:2;;;30:1;27;20:12;5:2;9426:219:16;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;9426:219:16;;:::i;:::-;;6314:160;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;6314:160:16;-1:-1:-1;;;;;6314:160:16;;:::i;566:130:0:-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;566:130:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;566:130:0;-1:-1:-1;;;;;566:130:0;;:::i;190:23:15:-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;190:23:15;;;:::i;:::-;;;;;;;;;;;;;;;;;;12821:114:16;;8:9:-1;5:2;;;30:1;27;20:12;5:2;12821:114:16;;;:::i;:::-;;;;-1:-1:-1;;;;;12821:114:16;;;;;;;;;;;;;;2388:111;;8:9:-1;5:2;;;30:1;27;20:12;5:2;2388:111:16;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;2388:111:16;;;;;;;;-1:-1:-1;5:28;;2:2;;;46:1;43;36:12;2:2;2388:111:16;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;2388:111:16;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;-1:-1;;;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;-1:-1;2388:111:16;;-1:-1:-1;2388:111:16;-1:-1:-1;2388:111:16;:::i;140:14:15:-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;140:14:15;;;:::i;3260:504:16:-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;3260:504:16;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;3260:504:16;-1:-1:-1;;;;;3260:504:16;;:::i;8439:656::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;8439:656:16;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;8439:656:16;;:::i;:::-;;;;;;;;;;;;;;;;1396:41;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1396:41:16;;;:::i;1443:46::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1443:46:16;;;:::i;2856:157::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;2856:157:16;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;2856:157:16;-1:-1:-1;;;;;2856:157:16;;:::i;1546:46::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1546:46:16;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;1546:46:16;-1:-1:-1;;;;;1546:46:16;;:::i;1414:83:15:-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1414:83:15;;;:::i;9852:2617:16:-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;9852:2617:16;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;9852:2617:16;;;;;;;;;;;;;;-1:-1:-1;5:28;;2:2;;;46:1;43;36:12;2:2;9852:2617:16;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;9852:2617:16;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;-1:-1;;;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;9852:2617:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;9852:2617:16;;-1:-1:-1;9852:2617:16;;-1:-1:-1;;;;;9852:2617:16:i;3770:1454::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;3770:1454:16;;;;;;;;;;;-1:-1:-1;;;;;3770:1454:16;;:::i;12475:118::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;12475:118:16;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;12475:118:16;;;;;;;;;;;;;;;;;1496:44;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1496:44:16;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;1496:44:16;-1:-1:-1;;;;;1496:44:16;;:::i;:::-;;;;-1:-1:-1;;;;;1496:44:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;702:167:0;;8:9:-1;5:2;;;30:1;27;20:12;5:2;702:167:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;702:167:0;-1:-1:-1;;;;;702:167:0;;:::i;12940:108:16:-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;12940:108:16;;;:::i;6480:1953::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;6480:1953:16;-1:-1:-1;;;;;6480:1953:16;;:::i;6201:107::-;;;:::i;12708:108::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;12708:108:16;;;:::i;433:26:0:-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;433:26:0;;;:::i;160:24:15:-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;160:24:15;;;:::i;:::-;;;;-1:-1:-1;;;;;160:24:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;160:24:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9222:143:16;;8:9:-1;5:2;;;30:1;27;20:12;5:2;9222:143:16;;;:::i;605:532:15:-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;605:532:15;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;605:532:15;:::i;397:30:0:-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;397:30:0;;;:::i;12599:104:16:-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;12599:104:16;;;:::i;2737:113::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;2737:113:16;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;2737:113:16;-1:-1:-1;;;;;2737:113:16;;:::i;2505:226::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;2505:226:16;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;2505:226:16;;;;;;;;-1:-1:-1;5:28;;2:2;;;46:1;43;36:12;2:2;2505:226:16;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;2505:226:16;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;-1:-1;;;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;-1:-1;2505:226:16;;-1:-1:-1;2505:226:16;-1:-1:-1;2505:226:16;:::i;1598:44::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1598:44:16;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;1598:44:16;-1:-1:-1;;;;;1598:44:16;;:::i;1689:36::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1689:36:16;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;1689:36:16;;:::i;9426:219::-;9546:6;:17;9535:46;;;-1:-1:-1;;;9535:46:16;;;;9487:26;;-1:-1:-1;;;;;9546:17:16;;9535:44;;:46;;;;;9546:17;;9535:46;;;;;;;9546:17;9535:46;;;5:2:-1;;;;30:1;27;20:12;5:2;9535:46:16;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;9535:46:16;;;;;;39:16:-1;36:1;17:17;2:54;101:4;9535:46:16;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;13:2;5:11;;2:2;;;29:1;26;19:12;2:2;9535:46:16;;;;;;;;;;;;;-1:-1:-1;11:20;;8:2;;;44:1;41;34:12;8:2;62:21;;;;123:4;114:14;;138:31;;;135:2;;;182:1;179;172:12;135:2;213:10;;-1:-1;244:29;;325:2;307:21;;285:44;;282:59;-1:-1;233:116;230:2;;;362:1;359;352:12;230:2;373:25;;-1:-1;9535:46:16;;421:4:-1;412:14;;;;9535:46:16;;;;;412:14:-1;9535:46:16;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;9535:46:16;;;;;;;;;;;9523:58;;9591:47;9613:13;9628:9;9591:21;:47::i;:::-;9426:219;;:::o;6314:160::-;6415:5;942:11:7;956:9;942:23;;6436:31:16::1;6454:12;6436:17;:31::i;:::-;986:12:7::0;1001:9;986:24;;1021:15;1047:8;:6;:8::i;:::-;-1:-1:-1;;;;;1039:30:7;;:32;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1039:32:7;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;1039:32:7;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;1039:32:7;;-1:-1:-1;1081:16:7;1100:71;1039:32;1141:20;1145:6;1153:7;1141:3;:20::i;:::-;1100:3;:71::i;:::-;1081:90;;1181:19;1212:10;:8;:10::i;:::-;-1:-1:-1;;;;;1203:32:7;;:34;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1203:34:7;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;1203:34:7;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;1203:34:7;;-1:-1:-1;1247:13:7;1276;:11;:13::i;:::-;-1:-1:-1;;;;;1263:43:7;;1320:11;1345:10;:8;:10::i;:::-;1263:127;;;-1:-1:-1;;;;;;1263:127:7;;;;;;;;;;;;;;-1:-1:-1;;;;;1263:127:7;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:2:-1;;;;30:1;27;20:12;5:2;1263:127:7;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;1263:127:7;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;1263:127:7;;-1:-1:-1;1400:20:7;1430:146;;;;1492:10;:8;:10::i;:::-;-1:-1:-1;;;;;1483:30:7;;:32;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1483:32:7;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;1483:32:7;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;1483:32:7;;-1:-1:-1;1430:146:7;;;-1:-1:-1;1564:1:7;1430:146;1619:30;1623:8;1633:15;1619:3;:30::i;:::-;1606:9;:43;;1585:123;;;;-1:-1:-1;;;1585:123:7;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1726:8;:6;:8::i;:::-;-1:-1:-1;;;;;1718:32:7;;1757:8;1718:50;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1718:50:7;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;1800:10:7;;-1:-1:-1;1800:151:7;;-1:-1:-1;1833:104:7;;-1:-1:-1;1858:24:7;;-1:-1:-1;1862:9:7;1873:8;1858:3;:24::i;:::-;1904:15;1833:3;:104::i;:::-;1800:151;;;;;;;;;;;;;;;;;;;;;1779:211;;;;;-1:-1:-1;;;1779:211:7;;;;;;;;;;;;-1:-1:-1;;;1779:211:7;;;;;;;;;;;;;;;2014:10;2005:69;2026:8;2036:20;2040:6;2048:7;2036:3;:20::i;:::-;2005:69;;;;;;;;;;;;;;;;;;;;;;;;;;;;6314:160:16;;;;;;;;;:::o;566:130:0:-;907:33;920:10;-1:-1:-1;;;;;;932:7:0;;;907:12;:33::i;:::-;899:66;;;;;-1:-1:-1;;;899:66:0;;;;;;;;;;;;-1:-1:-1;;;899:66:0;;;;;;;;;;;;;;;642:5:::1;:14:::0;;-1:-1:-1;;;;;;642:14:0::1;-1:-1:-1::0;;;;;642:14:0;;::::1;::::0;;;::::1;::::0;;;;671:18:::1;::::0;683:5;::::1;::::0;671:18:::1;::::0;-1:-1:-1;;671:18:0::1;566:130:::0;:::o;190:23:15:-;;;;;;:::o;12821:114:16:-;12895:7;12913:19;:17;:19::i;:::-;12906:26;;12821:114;:::o;2388:111::-;907:33:0;920:10;-1:-1:-1;;;;;;932:7:0;;;907:12;:33::i;:::-;899:66;;;;;-1:-1:-1;;;899:66:0;;;;;;;;;;;;-1:-1:-1;;;899:66:0;;;;;;;;;;;;;;;2466:26:16::1;2484:7;;2466:26;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16:::0;::::1;74:27:::0;;;;-1:-1;2466:17:16::1;::::0;-1:-1:-1;;;2466:26:16:i:1;140:14:15:-:0;;;-1:-1:-1;;;;;140:14:15;;:::o;3260:504:16:-;3320:4;3336:24;3376:13;:11;:13::i;:::-;3336:54;;3400:29;3459:11;-1:-1:-1;;;;;3459:25:16;;:27;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;3459:27:16;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;3459:27:16;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;3459:27:16;-1:-1:-1;;;;;3432:14:16;;;;;;:8;3459:27;3432:14;;;;:24;;;:54;;:110;;-1:-1:-1;3509:13:16;;3502:35;;;-1:-1:-1;;;3502:35:16;;;;-1:-1:-1;;;;;3509:13:16;;;;-1:-1:-1;;3509:13:16;3502:35;;;;;;;;;;;;;;3509:13;3502:35;;;5:2:-1;;;;30:1;27;20:12;5:2;3502:35:16;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;3502:35:16;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;3502:35:16;:40;3432:110;3400:142;;3560:16;3571:4;3560:10;:16::i;:::-;:56;;;;;3592:24;3560:56;:96;;;;;3633:23;3651:4;3633:17;:23::i;:::-;3632:24;3560:96;:147;;;;-1:-1:-1;;;;;;3672:14:16;;3706:1;3672:14;;;:8;:14;;;;;-1:-1:-1;3672:31:16;;:35;;3560:147;:197;;;;-1:-1:-1;;;;;;3723:14:16;;3756:1;3723:14;;;:8;:14;;;;;:30;;;:34;;3560:197;3553:204;3260:504;-1:-1:-1;;;;3260:504:16:o;8439:656::-;8589:13;;;8652:17;;8641:52;;;-1:-1:-1;;;8641:52:16;;;;8523:27;;-1:-1:-1;;;;;8589:13:16;;;;8523:27;;8652:17;;;;;-1:-1:-1;;8641:52:16;;;;;;;;;;;8523:27;8652:17;8641:52;;;5:2:-1;;;;30:1;27;20:12;5:2;8641:52:16;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;8641:52:16;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;8641:52:16;9008:20;;;-1:-1:-1;;;9008:20:16;;;;8641:52;;-1:-1:-1;8899:26:16;;9004:46;;-1:-1:-1;;;;;9008:18:16;;;-1:-1:-1;;9008:20:16;;;;;8641:52;;9008:20;;;;;;;;:18;:20;;;5:2:-1;;;;30:1;27;20:12;5:2;9008:20:16;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;9008:20:16;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;9008:20:16;9030:19;9004:3;:46::i;:::-;8928:73;8945:19;8978:13;8928:3;:73::i;:::-;:122;;;;;;;8439:656;-1:-1:-1;;;;;8439:656:16:o;1396:41::-;1435:2;1396:41;:::o;1443:46::-;1483:6;1443:46;:::o;2856:157::-;-1:-1:-1;;;;;2963:14:16;;2918:4;2963:14;;;:8;:14;;;;;:24;;;2959:47;;1483:6;2959:3;:47::i;:::-;2941:15;:65;;2856:157;-1:-1:-1;;2856:157:16:o;1546:46::-;;;;;;;;;;;;;;;:::o;1414:83:15:-;1480:14;;-1:-1:-1;;;;;1480:14:15;;1414:83::o;9852:2617:16:-;9977:13;;10022:28;;;-1:-1:-1;;;10022:28:16;;10039:10;9977:13;10022:28;;;;;-1:-1:-1;;;;;9977:13:16;;;;10054;;9977;;-1:-1:-1;;10022:28:16;;;;;;;;;;;;;;;9977:13;10022:28;;;5:2:-1;;;;30:1;27;20:12;5:2;10022:28:16;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;10022:28:16;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;10022:28:16;:45;;;;:93;;-1:-1:-1;10083:28:16;;;-1:-1:-1;;;10083:28:16;;10100:10;10083:28;;;;;;-1:-1:-1;;;;;;;10083:16:16;;;-1:-1:-1;;10083:28:16;;;;;;;;;;;;;;;:16;:28;;;5:2:-1;;;;30:1;27;20:12;5:2;10083:28:16;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;10083:28:16;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;10083:28:16;:32;10022:93;10001:193;;;;-1:-1:-1;;;10001:193:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10205:24;10273:13;:11;:13::i;:::-;10260:59;;-1:-1:-1;;;10260:59:16;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;10260:42:16;;;;;;;10303:15;;10260:59;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;10260:59:16;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;10260:59:16;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;10260:59:16;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;10260:59:16;:102;;;;-1:-1:-1;10349:3:16;;:13;;;-1:-1:-1;;;10349:13:16;;;;-1:-1:-1;;;;;10349:3:16;;;;:11;;:13;;;;;;;;;;;;;;;:3;:13;;;5:2:-1;;;;30:1;27;20:12;5:2;10349:13:16;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;10349:13:16;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;10349:13:16;-1:-1:-1;;;;;10335:27:16;:10;:27;;10260:102;10243:409;;;10398:17;;;10387:51;;;-1:-1:-1;;;10387:51:16;;;;-1:-1:-1;;;;;10398:17:16;;;;10387:49;;:51;;;;10398:17;;10387:51;;;;;;10398:17;;10387:51;;;5:2:-1;;;;30:1;27;20:12;5:2;10387:51:16;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;10387:51:16;;;;10474:37;10497:13;10474:22;:37::i;:::-;10525:50;;;-1:-1:-1;;;10525:50:16;;10543:10;10525:50;;;;;;;;;;;;;;-1:-1:-1;;;;;;10525:17:16;;;;;:50;;;;;-1:-1:-1;;10525:50:16;;;;;;;;-1:-1:-1;10525:17:16;:50;;;5:2:-1;;;;30:1;27;20:12;5:2;10525:50:16;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;10606:3:16;;:13;;;-1:-1:-1;;;10606:13:16;;;;-1:-1:-1;;;;;10589:16:16;;;;-1:-1:-1;10589:16:16;;-1:-1:-1;10606:3:16;;;;:11;;:13;;;;;;;;;;;;;;;:3;:13;;;5:2:-1;;;;30:1;27;20:12;5:2;10606:13:16;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;10606:13:16;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;10606:13:16;10589:52;;;-1:-1:-1;10589:52:16;;;-1:-1:-1;;;;;;10589:52:16;;;-1:-1:-1;;;;;10589:52:16;;;;;;;;;;;;;;;;;;;-1:-1:-1;;10589:52:16;;;;;;;-1:-1:-1;10589:52:16;;;;5:2:-1;;;;30:1;27;20:12;5:2;10589:52:16;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;10589:52:16;;;;10243:409;10661:27;10691:39;10695:13;10710:19;10691:3;:39::i;:::-;10661:69;;10741:15;10766:33;10813:15;:22;10802:34;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;10802:34:16;;10766:70;;10846:31;10894:15;:22;10880:37;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;10880:37:16;-1:-1:-1;11014:6:16;:17;10846:71;;-1:-1:-1;;;;;;11014:17:16;10979:21;11042:792;11063:15;:22;11059:1;:26;11042:792;;;11116:15;11132:1;11116:18;;;;;;;;;;;;;;;;;;;11173:33;;;-1:-1:-1;;;11173:33:16;;-1:-1:-1;;;;;11173:33:16;;;;;;;;;11116:18;;-1:-1:-1;11173:24:16;;;;;;:33;;;;;;;;;;:24;:33;;;5:2:-1;;;;30:1;27;20:12;5:2;11173:33:16;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;11173:33:16;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;11173:33:16;11148:125;;;;-1:-1:-1;;;11148:125:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11292:6;11287:212;11308:14;:21;11304:1;:25;11287:212;;;11394:14;11409:1;11394:17;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;11383:28:16;;;;;;;11354:130;;;;;-1:-1:-1;;;11354:130:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;11331:3;;11287:212;;;;11532:7;11512:14;11527:1;11512:17;;;;;;;;-1:-1:-1;;;;;11512:27:16;;;:17;;;;;;;;;;:27;;;;11573:33;;;-1:-1:-1;;;11573:33:16;;;;;;;;;;;-1:-1:-1;;11573:24:16;;;-1:-1:-1;;11573:33:16;;;;;;;;;;;-1:-1:-1;11573:24:16;:33;;;5:2:-1;;;;30:1;27;20:12;5:2;11573:33:16;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;11573:33:16;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;11573:33:16;;-1:-1:-1;11624:17:16;11620:31;;11643:8;;;11620:31;11803:6;-1:-1:-1;;;;;11803:18:16;;:20;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;11803:20:16;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;11803:20:16;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;11803:20:16;11759:41;11763:12;11777:22;11759:3;:41::i;:::-;:64;;;;;;11734:19;11754:1;11734:22;;;;;;;;;;;;;:89;;;;;11042:792;;11087:3;;11042:792;;;-1:-1:-1;11844:53:16;;;-1:-1:-1;;;11844:53:16;;11862:10;11844:53;;;;;;;;;;;;-1:-1:-1;;;;;11844:17:16;;;;;:53;;;;;-1:-1:-1;;11844:53:16;;;;;;;-1:-1:-1;11844:17:16;:53;;;5:2:-1;;;;30:1;27;20:12;5:2;11844:53:16;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;11946:6:16;;-1:-1:-1;;;11941:365:16;11962:15;:22;11958:1;:26;11941:365;;;12015:15;12031:1;12015:18;;;;;;;;;;;;;;12005:28;;12051:19;12071:1;12051:22;;;;;;;;;;;;;;12077:1;12051:27;12047:249;;;12098:8;;12047:249;12151:12;;12183:22;;-1:-1:-1;;;;;12151:12:16;;;;12145:28;;12174:7;;12183:22;;12203:1;;12183:22;;;;;;;;;;;;12145:61;;;;;;;;;;;;;-1:-1:-1;;;;;12145:61:16;-1:-1:-1;;;;;12145:61:16;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;12145:61:16;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;12145:61:16;;;;12224:57;12237:7;12246:10;12258:19;12278:1;12258:22;;;;;;;;;;;;;;12224:12;:57::i;:::-;11986:3;;11941:365;;;;12344:10;-1:-1:-1;;;;;12320:142:16;;12368:15;12397:19;12430:22;12320:142;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;12320:142:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;12320:142:16;;;;;;;;;;;;;;;;;;;;9852:2617;;;;;;;;;:::o;3770:1454::-;376:3:15;;:16;;;-1:-1:-1;;;;;;376:16:15;;;;-1:-1:-1;;;;;376:3:15;;;;:14;;:16;;;;;;;;;;;;;;;:3;:16;;;5:2:-1;;;;30:1;27;20:12;5:2;376:16:15;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;376:16:15;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;376:16:15;375:17;367:46;;;;;-1:-1:-1;;;367:46:15;;;;;;;;;;;;-1:-1:-1;;;367:46:15;;;;;;;;;;;;;;;3970:4:16::1;942:11:7;956:9;265:11:15::2;::::0;942:23:7;;-1:-1:-1;265:11:15::2;;257:53;;;::::0;;-1:-1:-1;;;257:53:15;;::::2;;::::0;::::2;::::0;::::2;::::0;;;;::::2;::::0;;;;;;;;;;;;;::::2;;4028:20:16::0;;4014:222:::3;::::0;;::::3;::::0;;::::3;::::0;;4097:10:::3;4014:222:::0;;-1:-1:-1;4014:222:16::3;::::0;;::::3;::::0;;;;;;;;;-1:-1:-1;;;;;4014:222:16;;::::3;::::0;;;;;;;;;;;;;;;;;;::::3;::::0;;;;;;;::::3;::::0;;;;;;;;;;;-1:-1:-1;;;4014:222:16;;4075:7;::::3;-1:-1:-1::0;;;;;;4075:7:16::3;4014:222;::::0;::::3;::::0;;;4028:20;;;::::3;::::0;-1:-1:-1;;4075:7:16;;4014:222;;;-1:-1:-1;4014:222:16;;;;;;;;;;-1:-1:-1;8:100:::3;33:3;30:1;27:10;8:100;;;90:11:::0;;::::3;84:18:::0;71:11;;::::3;64:39:::0;52:2:::3;45:10;8:100;;;12:14;4014:222:16;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11:::0;;::::3;84:18:::0;71:11;;::::3;64:39:::0;52:2:::3;45:10;8:100;;;12:14;4014:222:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27::::0;20:12:::3;5:2;4014:222:16;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::3;77:16;74:1;67:27;5:2;-1:-1:::0;;;;;;;;;4267:30:16;::::3;;::::0;;;:13:::3;:30;::::0;;;;;::::3;;4246:113;;;;-1:-1:-1::0;;;4246:113:16::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4369:100;4399:15;4416:10;4436:4;4443:16;4369;:100::i;:::-;4509:10;4500:20;::::0;;;:8:::3;:20;::::0;;;;:30:::3;;::::0;:35;4479:118:::3;;;;-1:-1:-1::0;;;4479:118:16::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4630:199;::::0;;::::3;::::0;;::::3;::::0;;-1:-1:-1;;;;;4630:199:16;;::::3;::::0;;;::::3;::::0;;::::3;::::0;;;;;;;;;4803:15:::3;4630:199:::0;;;;;;;4616:10:::3;-1:-1:-1::0;4607:20:16;;;:8:::3;:20:::0;;;;;:222;;;;-1:-1:-1;;;;;;4607:222:16::3;::::0;;::::3;;::::0;;;;-1:-1:-1;4607:222:16;::::3;::::0;;;::::3;::::0;::::3;::::0;;;::::3;::::0;;::::3;::::0;;;;4853:20;;4839:223;;-1:-1:-1;4839:223:16;;::::3;::::0;;;;;;;::::3;::::0;;;;;;;;;;;;;;;;;;;;;;;;;;::::3;::::0;;;;;;;::::3;::::0;;;;;;;;;;;-1:-1:-1;;;4839:223:16;;4901:7;::::3;-1:-1:-1::0;;;;;;4901:7:16::3;4839:223;::::0;::::3;::::0;;;4853:20;;;::::3;::::0;4839:48:::3;::::0;4901:7;;4839:223;;;-1:-1:-1;;4839:223:16;;;;;;;-1:-1:-1;4839:223:16;;-1:-1:-1;8:100:::3;33:3;30:1;27:10;8:100;;;90:11:::0;;::::3;84:18:::0;71:11;;::::3;64:39:::0;52:2:::3;45:10;8:100;;;12:14;4839:223:16;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11:::0;;::::3;84:18:::0;71:11;;::::3;64:39:::0;52:2:::3;45:10;8:100;;;12:14;4839:223:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27::::0;20:12:::3;5:2;4839:223:16;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::3;77:16;74:1;67:27;5:2;-1:-1:::0;;5078:139:16::3;::::0;;;;;::::3;::::0;::::3;::::0;;;;;-1:-1:-1;;;;;5078:139:16;::::3;::::0;-1:-1:-1;5109:10:16::3;::::0;-1:-1:-1;5078:139:16::3;::::0;;;;;;;;;::::3;986:12:7::1;1001:9;986:24;;1021:15;1047:8;:6;:8::i;:::-;-1:-1:-1::0;;;;;1039:30:7::1;;:32;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27::::0;20:12:::1;5:2;1039:32:7;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;1039:32:7;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26::::0;19:12:::1;2:2;-1:-1:::0;1039:32:7;;-1:-1:-1;1081:16:7::1;1100:71;1039:32:::0;1141:20:::1;1145:6:::0;1153:7;1141:3:::1;:20::i;1100:71::-;1081:90;;1181:19;1212:10;:8;:10::i;:::-;-1:-1:-1::0;;;;;1203:32:7::1;;:34;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27::::0;20:12:::1;5:2;1203:34:7;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;1203:34:7;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26::::0;19:12:::1;2:2;-1:-1:::0;1203:34:7;;-1:-1:-1;1247:13:7::1;1276;:11;:13::i;:::-;-1:-1:-1::0;;;;;1263:43:7::1;;1320:11:::0;1345:10:::1;:8;:10::i;:::-;1263:127;::::0;;-1:-1:-1;;;;;;1263:127:7::1;::::0;;;;;;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;;;1263:127:7;;::::1;::::0;;;;;;::::1;::::0;;;;;;;;;;::::1;::::0;;;;;;;;;;::::1;;5:2:-1::0;::::1;;;30:1;27::::0;20:12:::1;5:2;1263:127:7;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;1263:127:7;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26::::0;19:12:::1;2:2;-1:-1:::0;1263:127:7;;-1:-1:-1;1400:20:7::1;1430:146:::0;::::1;;;1492:10;:8;:10::i;:::-;-1:-1:-1::0;;;;;1483:30:7::1;;:32;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27::::0;20:12:::1;5:2;1483:32:7;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;1483:32:7;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26::::0;19:12:::1;2:2;-1:-1:::0;1483:32:7;;-1:-1:-1;1430:146:7::1;;;-1:-1:-1::0;1564:1:7::1;1430:146;1619:30;1623:8;1633:15;1619:3;:30::i;:::-;1606:9;:43;;1585:123;;;;-1:-1:-1::0;;;1585:123:7::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1726:8;:6;:8::i;:::-;-1:-1:-1::0;;;;;1718:32:7::1;;1757:8;1718:50;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27::::0;20:12:::1;5:2;1718:50:7;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;-1:-1:::0;1800:10:7::1;::::0;-1:-1:-1;1800:151:7::1;::::0;-1:-1:-1;1833:104:7::1;::::0;-1:-1:-1;1858:24:7::1;::::0;-1:-1:-1;1862:9:7::1;1873:8:::0;1858:3:::1;:24::i;1833:104::-;1800:151;::::0;;::::1;::::0;;::::1;::::0;::::1;::::0;;;;;;::::1;;;;;;1779:211;;;::::0;;-1:-1:-1;;;1779:211:7;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;1779:211:7;;;;;;;;;;;;;::::1;;2014:10;2005:69;2026:8:::0;2036:20:::1;2040:6:::0;2048:7;2036:3:::1;:20::i;:::-;2005:69;::::0;;;;;::::1;::::0;::::1;::::0;;;;;;;;;;;;;;;;;;::::1;423:1:15;;;;;;;;3770:1454:16::0;;;:::o;12475:118::-;12532:16;12567:19;12560:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;12560:26:16;;;-1:-1:-1;12560:26:16;;;;;;;;;;;;;;;;;;;12475:118;:::o;1496:44::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1496:44:16;;;;;;;:::o;702:167:0:-;907:33;920:10;-1:-1:-1;;;;;;932:7:0;;;907:12;:33::i;:::-;899:66;;;;;-1:-1:-1;;;899:66:0;;;;;;;;;;;;-1:-1:-1;;;899:66:0;;;;;;;;;;;;;;;790:9:::1;:22:::0;;-1:-1:-1;;;;;;790:22:0::1;-1:-1:-1::0;;;;;790:22:0;;::::1;::::0;;;::::1;::::0;;;827:35:::1;::::0;851:9;::::1;::::0;827:35:::1;::::0;::::1;702:167:::0;:::o;12940:108:16:-;13011:7;13029:16;:14;:16::i;6480:1953::-;376:3:15;;:16;;;-1:-1:-1;;;;;;376:16:15;;;;-1:-1:-1;;;;;376:3:15;;;;:14;;:16;;;;;;;;;;;;;;;:3;:16;;;5:2:-1;;;;30:1;27;20:12;5:2;376:16:15;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;376:16:15;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;376:16:15;375:17;367:46;;;;;-1:-1:-1;;;367:46:15;;;;;;;;;;;;-1:-1:-1;;;367:46:15;;;;;;;;;;;;;;;6586:5:16::1;942:11:7::0;956:9:::1;942:23;;6623:22:16::2;;:::i;:::-;-1:-1:-1::0;;;;;;6648:22:16;;::::2;;::::0;;;:8:::2;:22;::::0;;;;;;;;6623:47;;::::2;::::0;::::2;::::0;;;;;;::::2;::::0;;-1:-1:-1;6623:47:16;::::2;::::0;;;::::2;::::0;;;;::::2;::::0;::::2;::::0;;;;;;;;::::2;;::::0;;;;;6701:29:::2;6648:22:::0;6701:15:::2;:29::i;:::-;6680:109;;;;-1:-1:-1::0;;;6680:109:16::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6811:17:::0;;;6800:51:::2;::::0;;-1:-1:-1;;;6800:51:16;;;;-1:-1:-1;;;;;6811:17:16;;::::2;::::0;6800:49:::2;::::0;:51;;::::2;::::0;6811:17:::2;::::0;6800:51;;;;;;6811:17;;6800:51;::::2;;5:2:-1::0;::::2;;;30:1;27::::0;20:12:::2;5:2;6800:51:16;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::2;77:16;74:1;67:27;5:2;-1:-1:::0;;6912:6:16::2;:17:::0;6981:23:::2;::::0;;::::2;::::0;7022;;6901:158;;-1:-1:-1;;;6901:158:16;;::::2;::::0;::::2;::::0;;;;-1:-1:-1;;;;;6901:158:16;;::::2;::::0;;;;;;-1:-1:-1;;;6912:17:16;;;::::2;::::0;-1:-1:-1;;;6901:158:16;;;;;::::2;::::0;;;;;;;;;-1:-1:-1;6912:17:16;6901:158;::::2;;5:2:-1::0;::::2;;;30:1;27::::0;20:12:::2;5:2;6901:158:16;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::2;77:16;74:1;67:27;5:2;6901:158:16;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26::::0;19:12:::2;2:2;-1:-1:::0;6901:158:16;::::2;7126:24:::0;::::2;::::0;6901:158;;-1:-1:-1;7091:59:16;::::2;;7070:129;;;::::0;;-1:-1:-1;;;7070:129:16;;::::2;;::::0;::::2;::::0;::::2;::::0;;;;::::2;::::0;;;;;;;;;;;;;::::2;;7296:23:::0;;7333:12;;7270:130:::2;::::0;7296:23;-1:-1:-1;;;;;7333:12:16::2;7359:31:::0;7270:12:::2;:130::i;:::-;7411:26;7440:96;7457:7;:24;;;7495:31;7440:3;:96::i;:::-;7411:125:::0;-1:-1:-1;7609:25:16;;7605:192:::2;;7680:23:::0;;7650:136:::2;::::0;7721:12;7751:21;7650:12:::2;:136::i;:::-;7836:15:::0;;7827:37:::2;::::0;;-1:-1:-1;;;7827:37:16;;;;7807:10:::2;::::0;:58:::2;::::0;-1:-1:-1;;;;;7836:15:16;;::::2;::::0;7827:35:::2;::::0;:37:::2;::::0;;::::2;::::0;::::2;::::0;;;;;;;;;7836:15;7827:37;::::2;;5:2:-1::0;::::2;;;30:1;27::::0;20:12:::2;5:2;7827:37:16;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::2;77:16;74:1;67:27;5:2;7827:37:16;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26::::0;19:12:::2;2:2;-1:-1:::0;7827:37:16;7807:58:::2;::::0;;::::2;::::0;;::::2;::::0;::::2;::::0;;;7827:37;7807:58;;::::2;;;;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::2;77:16;74:1;67:27;5:2;-1:-1:::0;7883:13:16;;7922:23:::2;::::0;;::::2;::::0;7876:70;;-1:-1:-1;;;7876:70:16;;-1:-1:-1;;;;;7876:70:16;;::::2;7883:13;7876:70:::0;::::2;::::0;;;;;;;;;;7883:13;::::2;::::0;7876:31:::2;::::0;:70;;;;;-1:-1:-1;;7876:70:16;;;;;;;;-1:-1:-1;7883:13:16;7876:70;::::2;;5:2:-1::0;::::2;;;30:1;27::::0;20:12:::2;5:2;7876:70:16;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::2;77:16;74:1;67:27;5:2;-1:-1:::0;;7967:6:16::2;:17:::0;8008:23;;7956:76:::2;::::0;;-1:-1:-1;;;7956:76:16;;-1:-1:-1;;;;;7956:76:16;;::::2;;::::0;::::2;::::0;;;7967:17;;;::::2;::::0;-1:-1:-1;7956:51:16::2;::::0;-1:-1:-1;7956:76:16;;;;;-1:-1:-1;;7956:76:16;;;;;;;-1:-1:-1;7967:17:16;7956:76;::::2;;5:2:-1::0;::::2;;;30:1;27::::0;20:12:::2;5:2;7956:76:16;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::2;77:16;74:1;67:27;5:2;-1:-1:::0;;;;;;;;;8048:25:16;::::2;;::::0;;;:11:::2;:25;::::0;;;;;::::2;;8043:141;;-1:-1:-1::0;;;;;8089:25:16;::::2;;::::0;;;:11:::2;:25;::::0;;;;:32;;-1:-1:-1;;8089:32:16::2;-1:-1:-1::0;8089:32:16;;::::2;::::0;;;8135:19:::2;27:10:-1::0;;23:18;;::::2;45:23:::0;;8135:38:16;;;;::::2;::::0;;-1:-1:-1;;;;;;8135:38:16::2;::::0;;::::2;::::0;;8043:141:::2;8279:23:::0;;8316:24:::2;::::0;;::::2;::::0;8354:23:::2;::::0;;::::2;::::0;8199:188;;;;;;;::::2;::::0;;;;;;-1:-1:-1;;;;;8199:188:16;;::::2;::::0;8255:10:::2;::::0;8199:188;;::::2;::::0;::::2;::::0;;;;;;;;;::::2;-1:-1:-1::0;;;;;;;;8404:22:16;::::2;;::::0;;;:8:::2;:22;::::0;;;;8397:29;;-1:-1:-1;;;;;;8397:29:16::2;::::0;;-1:-1:-1;8397:29:16;::::2;::::0;;;::::2;::::0;::::2;::::0;;;::::2;;::::0;;;1001:9:7::1;986:24;;1021:15;1047:8;:6;:8::i;6201:107:16:-:0;6255:5;942:11:7;956:9;942:23;;6272:29:16::1;6290:10;6272:17;:29::i;:::-;986:12:7::0;1001:9;986:24;;1021:15;1047:8;:6;:8::i;:::-;-1:-1:-1;;;;;1039:30:7;;:32;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1039:32:7;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;1039:32:7;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;1039:32:7;;-1:-1:-1;1081:16:7;1100:71;1039:32;1141:20;1145:6;1153:7;1141:3;:20::i;1100:71::-;1081:90;;1181:19;1212:10;:8;:10::i;:::-;-1:-1:-1;;;;;1203:32:7;;:34;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1203:34:7;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;1203:34:7;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;1203:34:7;;-1:-1:-1;1247:13:7;1276;:11;:13::i;:::-;-1:-1:-1;;;;;1263:43:7;;1320:11;1345:10;:8;:10::i;:::-;1263:127;;;-1:-1:-1;;;;;;1263:127:7;;;;;;;;;;;;;;-1:-1:-1;;;;;1263:127:7;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:2:-1;;;;30:1;27;20:12;5:2;1263:127:7;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;1263:127:7;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;1263:127:7;;-1:-1:-1;1400:20:7;1430:146;;;;1492:10;:8;:10::i;:::-;-1:-1:-1;;;;;1483:30:7;;:32;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1483:32:7;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;1483:32:7;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;1483:32:7;;-1:-1:-1;1430:146:7;;;-1:-1:-1;1564:1:7;1430:146;1619:30;1623:8;1633:15;1619:3;:30::i;:::-;1606:9;:43;;1585:123;;;;-1:-1:-1;;;1585:123:7;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1726:8;:6;:8::i;:::-;-1:-1:-1;;;;;1718:32:7;;1757:8;1718:50;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1718:50:7;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;1800:10:7;;-1:-1:-1;1800:151:7;;-1:-1:-1;1833:104:7;;-1:-1:-1;1858:24:7;;-1:-1:-1;1862:9:7;1873:8;1858:3;:24::i;1833:104::-;1800:151;;;;;;;;;;;;;;;;;;;;;1779:211;;;;;-1:-1:-1;;;1779:211:7;;;;;;;;;;;;-1:-1:-1;;;1779:211:7;;;;;;;;;;;;;;;2014:10;2005:69;2026:8;2036:20;2040:6;2048:7;2036:3;:20::i;:::-;2005:69;;;;;;;;;;;;;;;;;;;;;;;;;;;;6201:107:16;;;;;;;;:::o;12708:108::-;12779:7;12797:16;:14;:16::i;433:26:0:-;;;-1:-1:-1;;;;;433:26:0;;:::o;160:24:15:-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;160:24:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;9222:143:16:-;9285:13;;9278:43;;;-1:-1:-1;;;9278:43:16;;9310:10;9285:13;9278:43;;;;;-1:-1:-1;;;;;;;9285:13:16;;-1:-1:-1;;9278:43:16;;;;;;;;;;;;;;9285:13;9278:43;;;5:2:-1;;;;30:1;27;20:12;5:2;9278:43:16;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;9278:43:16;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;9278:43:16;;-1:-1:-1;9331:27:16;9278:43;9331:14;:27::i;:::-;9222:143;:::o;605:532:15:-;907:33:0;920:10;-1:-1:-1;;;;;;932:7:0;;;907:12;:33::i;:::-;899:66;;;;;-1:-1:-1;;;899:66:0;;;;;;;;;;;;-1:-1:-1;;;899:66:0;;;;;;;;;;;;;;;709:3:15::1;::::0;-1:-1:-1;;;;;709:3:15::1;687:10;:26;679:35;;;::::0;::::1;;733:11;::::0;::::1;;732:12;724:44;;;::::0;;-1:-1:-1;;;724:44:15;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;724:44:15;;;;;;;;;;;;;::::1;;787:285;::::0;;::::1;::::0;::::1;::::0;;-1:-1:-1;;;;;811:10:15;::::1;::::0;::::1;787:285:::0;;;811:10:::1;835::::0;;::::1;;::::0;::::1;787:285:::0;;::::1;::::0;;;859:10;;::::1;;::::0;::::1;787:285:::0;;;;;;;883:10;;::::1;;::::0;::::1;787:285:::0;;;;;;;907:10;;::::1;;::::0;::::1;787:285:::0;;;;;;;931:10;;::::1;;::::0;::::1;787:285:::0;;;;;;;955:10;;::::1;;::::0;::::1;787:285:::0;;;;;;;979:10;;::::1;;::::0;::::1;787:285:::0;;;;;;;1003:10;;::::1;;::::0;::::1;787:285:::0;;;;;;;1027:10;;::::1;;::::0;::::1;787:285:::0;;;;;;;1051:11;;::::1;;::::0;;::::1;787:285:::0;;;;;;;778:6:::1;:294:::0;;-1:-1:-1;;;;;;778:294:15;;::::1;::::0;;::::1;::::0;;915:1:::1;778:294:::0;;;::::1;::::0;;::::1;::::0;;;939:1:::1;778:294:::0;;;::::1;::::0;;::::1;::::0;;;963:1:::1;778:294:::0;;;::::1;::::0;;::::1;::::0;;;987:1:::1;778:294:::0;;;::::1;::::0;;::::1;::::0;;;1011:1:::1;778:294:::0;;;::::1;::::0;;::::1;::::0;;1035:1:::1;778:294:::0;;;::::1;::::0;;::::1;::::0;;1059:2:::1;778:294:::0;;;::::1;::::0;;::::1;::::0;;;;;;;::::1;::::0;;::::1;::::0;;;;;;;::::1;::::0;;::::1;::::0;;;;;;;;::::1;;::::0;;1082:11:::1;:18:::0;;-1:-1:-1;;1082:18:15::1;-1:-1:-1::0;1082:18:15::1;::::0;;1110:20:::1;-1:-1:-1::0;1110:8:15::1;:20::i;397:30:0:-:0;;;-1:-1:-1;;;;;397:30:0;;:::o;12599:104:16:-;12668:7;12686:14;:12;:14::i;2737:113::-;-1:-1:-1;;;;;2815:14:16;2792:4;2815:14;;;:8;:14;;;;;:24;;;:28;;;2737:113::o;2505:226::-;907:33:0;920:10;-1:-1:-1;;;;;;932:7:0;;;907:12;:33::i;:::-;899:66;;;;;-1:-1:-1;;;899:66:0;;;;;;;;;;;;-1:-1:-1;;;899:66:0;;;;;;;;;;;;;;;2589:6:16::1;2584:100;2601:18:::0;;::::1;2584:100;;;2668:5;2640:13;:25;2654:7;;2662:1;2654:10;;;;;;;;::::0;;::::1;::::0;;;::::1;;-1:-1:-1::0;;;;;2654:10:16::1;2640:25:::0;;-1:-1:-1;2640:25:16;::::1;::::0;;;;;;-1:-1:-1;2640:25:16;:33;;-1:-1:-1;;2640:33:16::1;::::0;::::1;;::::0;;;::::1;::::0;;-1:-1:-1;2621:3:16::1;2584:100;;;;2698:26;2716:7;;2698:26;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16:::0;;::::1;74:27:::0;2698:26:16::1;::::0;137:4:-1::1;117:14:::0;;::::1;-1:-1:::0;;113:30:::1;157:16:::0;;::::1;2698:26:16::0;;::::1;::::0;-1:-1:-1;2698:26:16;;-1:-1:-1;;;;2698:26:16::1;2505:226:::0;;:::o;1598:44::-;;;;;;;;;;;;;;;:::o;1689:36::-;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1689:36:16;;-1:-1:-1;1689:36:16;:::o;5230:827::-;5306:24;5317:12;5306:10;:24::i;:::-;5298:57;;;;;-1:-1:-1;;;5298:57:16;;;;;;;;;;;;-1:-1:-1;;;5298:57:16;;;;;;;;;;;;;;;5365:24;5405:13;:11;:13::i;:::-;5365:54;;5429:22;;:::i;:::-;-1:-1:-1;;;;;;5454:22:16;;;;;;;:8;:22;;;;;;;;;5429:47;;;;;;;;;;;;;;-1:-1:-1;5429:47:16;;;;;;;;;;;;;;;;;;;;;;;;5508:50;;-1:-1:-1;;;5508:50:16;;;;;;;;;;;5429:47;;5508:25;;;-1:-1:-1;;5508:50:16;;;;;5454:22;;5508:50;;;;;;:25;:50;;;5:2:-1;;;;30:1;27;20:12;5:2;5508:50:16;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;5508:50:16;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;5508:50:16;5507:51;;:98;;;5574:31;5592:12;5574:17;:31::i;:::-;5507:130;;;-1:-1:-1;5621:3:16;;:16;;;-1:-1:-1;;;;;;5621:16:16;;;;-1:-1:-1;;;;;5621:3:16;;;;:14;;:16;;;;;;;;;;;;;;;:3;:16;;;5:2:-1;;;;30:1;27;20:12;5:2;5621:16:16;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;5621:16:16;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;5621:16:16;5507:130;5486:210;;;;-1:-1:-1;;;5486:210:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5738:23;;5796:24;;;;;-1:-1:-1;;;;;5837:22:16;;;5706;5837;;;:8;:22;;;;;;5830:29;;-1:-1:-1;;;;;;5830:29:16;;;-1:-1:-1;5830:29:16;;;;;;;;;;;;;;;;;5898:15;;5889:37;;-1:-1:-1;;;5889:37:16;;;;5796:24;;5869:10;;:58;;5898:15;;;;;5889:35;;:37;;;;;5796:24;5889:37;;;;;5898:15;5889:37;;;5:2:-1;;;;30:1;27;20:12;5:2;5889:37:16;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;5889:37:16;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;5889:37:16;5869:58;;;;;;;;;;;;5889:37;5869:58;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;5869:58:16;5937:70;5958:15;5976:12;5990:16;5937:12;:70::i;:::-;6023:27;;-1:-1:-1;;;;;6023:27:16;;;;;;;;5230:827;;;;;:::o;877:127:2:-;960:5;;;955:16;;;;947:50;;;;;-1:-1:-1;;;947:50:2;;;;;;;;;;;;-1:-1:-1;;;947:50:2;;;;;;;;;;;;;;;877:127;;;;:::o;1009:140::-;1061:6;1087;;;:30;;-1:-1:-1;;1102:5:2;;;1116:1;1111;1102:5;1111:1;1097:15;;;;;:20;1087:30;1079:63;;;;;-1:-1:-1;;;1079:63:2;;;;;;;;;;;;-1:-1:-1;;;1079:63:2;;;;;;;;;;;;;;746:126;829:5;;;824:16;;;;816:49;;;;;-1:-1:-1;;;816:49:2;;;;;;;;;;;;-1:-1:-1;;;816:49:2;;;;;;;;;;;;;;989:370:0;1059:4;1094;-1:-1:-1;;;;;1079:20:0;;;1075:278;;;-1:-1:-1;1122:4:0;1115:11;;1075:278;1154:5;;-1:-1:-1;;;;;1147:12:0;;;1154:5;;1147:12;1143:210;;;-1:-1:-1;1182:4:0;1175:11;;1143:210;1232:1;1207:9;-1:-1:-1;;;;;1207:9:0;1203:150;;-1:-1:-1;1257:5:0;1250:12;;1203:150;1300:9;;:42;;;-1:-1:-1;;;1300:42:0;;-1:-1:-1;;;;;1300:42:0;;;;;;;1331:4;1300:42;;;;-1:-1:-1;;;;;;1300:42:0;;;;;;;;:9;;;;;-1:-1:-1;;1300:42:0;;;;;;;;;;;;;;:9;:42;;;5:2:-1;;;;30:1;27;20:12;5:2;1300:42:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;1300:42:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;1300:42:0;;-1:-1:-1;1293:49:0;;1319:90:15;1389:3;;:17;;;-1:-1:-1;;;1389:17:15;;;;1371:7;;-1:-1:-1;;;;;1389:3:15;;-1:-1:-1;;1389:17:15;;;;;;;;;;;;;;:3;:17;;;5:2:-1;;;;30:1;27;20:12;5:2;1389:17:15;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;1389:17:15;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;1389:17:15;;-1:-1:-1;1319:90:15;:::o;2017:365:16:-;2094:6;2089:247;2110:7;:14;2106:1;:18;2089:247;;;2179:15;;2214:10;;-1:-1:-1;;;;;2179:15:16;;;;2170:43;;2214:10;;2222:1;;2214:10;;;;;;;;;;;;;;;;;2170:55;;;-1:-1:-1;;;;;;2170:55:16;;;;;;;-1:-1:-1;;;;;2170:55:16;;;;;;;;;;;;;2214:10;2170:55;;;;;;;;;5:2:-1;;;;30:1;27;20:12;5:2;2170:55:16;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;2170:55:16;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;2170:55:16;2145:134;;;;;-1:-1:-1;;;2145:134:16;;;;;;;;;;;;-1:-1:-1;;;2145:134:16;;;;;;;;;;;;;;;2321:4;2293:13;:25;2307:7;2315:1;2307:10;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;2293:25:16;;;;;;;;;;;-1:-1:-1;2293:25:16;:32;;-1:-1:-1;;2293:32:16;;;;;;;;;;-1:-1:-1;2126:3:16;2089:247;;;;2350:25;2367:7;2350:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;2350:25:16;;;;;;;;;;;;;;;;;2017:365;:::o;162:441:4:-;301:29;;;-1:-1:-1;;;301:29:4;;-1:-1:-1;;;;;301:29:4;;;;;;;;;275:23;;301:24;;;;;:29;;;;;;;;;;;;;;:24;:29;;;5:2:-1;;;;30:1;27;20:12;5:2;301:29:4;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;301:29:4;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;301:29:4;340:36;;;-1:-1:-1;;;340:36:4;;-1:-1:-1;;;;;340:36:4;;;;;;;;;;;;;;;301:29;;-1:-1:-1;340:23:4;;;;-1:-1:-1;;340:36:4;;;;;301:29;;340:36;;;;;;;;-1:-1:-1;340:23:4;:36;;;5:2:-1;;;;30:1;27;20:12;5:2;340:36:4;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;340:36:4;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;413:29:4;;;-1:-1:-1;;;413:29:4;;-1:-1:-1;;;;;413:29:4;;;;;;;;;-1:-1:-1;;413:24:4;;;-1:-1:-1;;413:29:4;;;;;340:36;;413:29;;;;;;;:24;:29;;;5:2:-1;;;;30:1;27;20:12;5:2;413:29:4;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;413:29:4;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;413:29:4;;-1:-1:-1;413:29:4;473:31;477:18;497:6;473:3;:31::i;:::-;:54;452:144;;;;-1:-1:-1;;;452:144:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;162:441;;;;;:::o;609:483::-;775:29;;;-1:-1:-1;;;775:29:4;;-1:-1:-1;;;;;775:29:4;;;;;;;;;749:23;;775:24;;;;;:29;;;;;;;;;;;;;;:24;:29;;;5:2:-1;;;;30:1;27;20:12;5:2;775:29:4;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;775:29:4;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;775:29:4;814:47;;;-1:-1:-1;;;814:47:4;;-1:-1:-1;;;;;814:47:4;;;;;;;;;;;;;;;;;;;;;;775:29;;-1:-1:-1;814:27:4;;;;-1:-1:-1;;814:47:4;;;;;775:29;;814:47;;;;;;;;-1:-1:-1;814:27:4;:47;;;5:2:-1;;;;30:1;27;20:12;5:2;814:47:4;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;814:47:4;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;898:29:4;;;-1:-1:-1;;;898:29:4;;-1:-1:-1;;;;;898:29:4;;;;;;;;;-1:-1:-1;;898:24:4;;;-1:-1:-1;;898:29:4;;;;;814:47;;898:29;;;;;;;:24;:29;;;5:2:-1;;;;30:1;27;20:12;5:2;898:29:4;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;898:29:4;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;898:29:4;;-1:-1:-1;898:29:4;958:31;962:18;982:6;958:3;:31::i;:::-;:54;937:148;;;;-1:-1:-1;;;937:148:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;609:483;;;;;;:::o;1502:85:15:-;1569:15;;-1:-1:-1;;;;;1569:15:15;;1502:85::o;1229:::-;1296:15;;-1:-1:-1;;;;;1296:15:15;;1229:85::o;1143:81::-;1208:13;;-1:-1:-1;;;;;1208:13:15;;1143:81::o;483:12567:16:-;;;;;;;;;-1:-1:-1;483:12567:16;;;;;;;;;;;;;;;;;;;;;;;:::o
Swarm Source
ipfs://c8c881c31bf73e6260fa333441b2a86f898fe182daeacbdee21155d2d6683c2d
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
[ 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.