Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 11,446 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Meta Fill Orders | 10717693 | 1431 days ago | IN | 0 ETH | 0.02439336 | ||||
Meta Fill Orders | 10712071 | 1431 days ago | IN | 0 ETH | 0.01785437 | ||||
Meta Fill Orders | 10705137 | 1432 days ago | IN | 0 ETH | 0.04370108 | ||||
Meta Fill Orders | 10698908 | 1433 days ago | IN | 0 ETH | 0.02637647 | ||||
Meta Fill Orders | 10691540 | 1435 days ago | IN | 0 ETH | 0.03916815 | ||||
Meta Fill Orders | 10691536 | 1435 days ago | IN | 0 ETH | 0.03695535 | ||||
Meta Fill Orders | 10686799 | 1435 days ago | IN | 0 ETH | 0.02786019 | ||||
Meta Fill Orders | 10686251 | 1435 days ago | IN | 0 ETH | 0.02935251 | ||||
Meta Fill Orders | 10683526 | 1436 days ago | IN | 0 ETH | 0.04815148 | ||||
Meta Fill Orders | 10683520 | 1436 days ago | IN | 0 ETH | 0.03570966 | ||||
Meta Fill Orders | 10682911 | 1436 days ago | IN | 0 ETH | 0.05760161 | ||||
Meta Fill Orders | 10682216 | 1436 days ago | IN | 0 ETH | 0.04889755 | ||||
Meta Fill Orders | 10682022 | 1436 days ago | IN | 0 ETH | 0.03318334 | ||||
Meta Fill Orders | 10680665 | 1436 days ago | IN | 0 ETH | 0.02424358 | ||||
Meta Fill Orders | 10679310 | 1436 days ago | IN | 0 ETH | 0.02589224 | ||||
Meta Fill Orders | 10679310 | 1436 days ago | IN | 0 ETH | 0.0266397 | ||||
Meta Fill Orders | 10679265 | 1436 days ago | IN | 0 ETH | 0.0605922 | ||||
Meta Fill Orders | 10679104 | 1436 days ago | IN | 0 ETH | 0.03196968 | ||||
Meta Fill Orders | 10679050 | 1436 days ago | IN | 0 ETH | 0.03223694 | ||||
Meta Fill Orders | 10678847 | 1436 days ago | IN | 0 ETH | 0.0616542 | ||||
Meta Fill Orders | 10678826 | 1436 days ago | IN | 0 ETH | 0.04262416 | ||||
Meta Fill Orders | 10678708 | 1437 days ago | IN | 0 ETH | 0.04556141 | ||||
Meta Fill Orders | 10678682 | 1437 days ago | IN | 0 ETH | 0.04556568 | ||||
Meta Fill Orders | 10678614 | 1437 days ago | IN | 0 ETH | 0.04608668 | ||||
Meta Fill Orders | 10678612 | 1437 days ago | IN | 0 ETH | 0.05098527 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
FillOrder
Compiler Version
v0.5.16+commit.9c3226ce
Contract Source Code (Solidity Standard Json-Input format)
pragma solidity 0.5.16; pragma experimental ABIEncoderV2; import "./BaseFillOrder.sol"; import "../../interfaces/trading/IFillOrder.sol"; import "../../interfaces/trading/IEIP712FillHasher.sol"; /// @title MultiFillOrder /// @author Julian Wilson <[email protected]> /// @notice Manages the public functionality to fill multiple orders at once contract FillOrder is IFillOrder, BaseFillOrder { IEIP712FillHasher internal eip712FillHasher; constructor(ISuperAdminRole _superAdminRole, IEIP712FillHasher _eip712FillHasher) public BaseFillOrder(_superAdminRole) { eip712FillHasher = _eip712FillHasher; } /// @notice Fills a bunch of orders simulatenously. /// @param fillDetails The fills to execute. /// @param executorSig The signature of the executor on this fill if the executor is set. function fillOrders( LibOrder.FillDetails memory fillDetails, bytes memory executorSig ) public { address executor = fillDetails.fills.orders[0].executor; bytes32 fillHash; require( fillDetails.fills.orders.length == fillDetails.fills.takerAmounts.length && fillDetails.fills.orders.length == fillDetails.fills.makerSigs.length, "INCORRECT_ARRAY_LENGTHS" ); if (executor != address(0)) { fillHash = eip712FillHasher.getDetailsHash(fillDetails); require( fills.getFillHashSubmitted(fillHash) == false, "FILL_ALREADY_SUBMITTED" ); require( ECDSA.recover( fillHash, executorSig ) == executor, "EXECUTOR_SIGNATURE_MISMATCH" ); if (fillDetails.fills.orders.length > 1) { for (uint256 i = 1; i < fillDetails.fills.orders.length; i++) { require( fillDetails.fills.orders[i].executor == executor, "INCONSISTENT_EXECUTORS" ); } } fills.setFillHashSubmitted(fillHash); } _fillOrders( fillDetails.fills.orders, fillDetails.fills.takerAmounts, fillDetails.fills.makerSigs, msg.sender, fillHash ); } /// @notice Fills a bunch of orders simulatenously in meta fashion /// @param fillDetails The details of the fill /// @param taker The taker for this fill. /// @param takerSig The signature of the taker for this fill. /// @param executorSig The signature of the executor on this order if the executor is set. function metaFillOrders( LibOrder.FillDetails memory fillDetails, address taker, bytes memory takerSig, bytes memory executorSig ) public { bytes32 fillHash = eip712FillHasher.getDetailsHash(fillDetails); require( ECDSA.recover( fillHash, takerSig ) == taker, "TAKER_SIGNATURE_MISMATCH" ); require( fills.getFillHashSubmitted(fillHash) == false, "FILL_ALREADY_SUBMITTED" ); address executor = fillDetails.fills.orders[0].executor; if (executor != address(0)) { require( msg.sender == executor, "SENDER_MUST_BE_EXECUTOR" ); require( ECDSA.recover( fillHash, executorSig ) == executor, "EXECUTOR_SIGNATURE_MISMATCH" ); } require( fillDetails.fills.orders.length == fillDetails.fills.takerAmounts.length && fillDetails.fills.orders.length == fillDetails.fills.makerSigs.length, "INCORRECT_ARRAY_LENGTHS" ); if (fillDetails.fills.orders.length > 1) { for (uint256 i = 1; i < fillDetails.fills.orders.length; i++) { require( fillDetails.fills.orders[i].executor == executor, "INCONSISTENT_EXECUTORS" ); } } _fillOrders( fillDetails.fills.orders, fillDetails.fills.takerAmounts, fillDetails.fills.makerSigs, taker, fillHash ); fills.setFillHashSubmitted(fillHash); } /// @notice Internal method to fill multiple orders. /// Checks if the fill can be optimized for the taker (i.e., transfers can be combined). /// @param makerOrders The orders to fill. /// @param takerAmounts The amount to fill for each order. /// @param makerSigs The maker signatures for each order. /// @param taker The taker of these orders. /// @param fillHash The fill hash, if applicable in the case of a meta fill. function _fillOrders( LibOrder.Order[] memory makerOrders, uint256[] memory takerAmounts, bytes[] memory makerSigs, address taker, bytes32 fillHash ) private { bool areOrdersSimilar = areOrdersValidAndSimilar( makerOrders, takerAmounts, makerSigs, taker ); // If we get here they are valid so no need to check again if (areOrdersSimilar) { _fillSimilarOrders( makerOrders, takerAmounts, taker, fillHash ); } else { for (uint256 i = 0; i < makerOrders.length; i++) { _fillSingleOrder( makerOrders[i], takerAmounts[i], taker, fillHash ); } } } /// @notice Internal method to fill multiple similar orders /// Here, the taker transfers are batched to save gas. /// @param makerOrders The orders to fill. /// @param takerAmounts The amount to fill for each order. /// @param taker The taker of these orders. /// @param fillHash The fill hash, if applicable in the case of a meta fill. function _fillSimilarOrders( LibOrder.Order[] memory makerOrders, uint256[] memory takerAmounts, address taker, bytes32 fillHash ) private { LibOrderAmounts.OrderAmounts memory totalOrderAmounts = LibOrderAmounts.computeTotalOrderAmounts( makerOrders, takerAmounts ); settleOrderForTaker( makerOrders[0], totalOrderAmounts, taker ); settleOrdersForMaker( makerOrders, takerAmounts, taker, fillHash ); } /// @notice Checks if orders are valid and similar. /// If they are, then we can optimize the fill /// @param makerOrders The orders to fill. /// @param takerAmounts The amount to fill for each order. /// @param makerSigs The maker signatures for each order. /// @param taker The taker of these orders. function areOrdersValidAndSimilar( LibOrder.Order[] memory makerOrders, uint256[] memory takerAmounts, bytes[] memory makerSigs, address taker ) private view returns (bool) { bool isMakerBettingOutcomeOne = makerOrders[0].isMakerBettingOutcomeOne; bytes32 marketHash = makerOrders[0].marketHash; address baseToken = makerOrders[0].baseToken; for (uint256 i = 0; i < makerOrders.length; i++) { assertOrderValid( makerOrders[i], takerAmounts[i], taker, makerSigs[i] ); } if (makerOrders.length > 1) { for (uint256 i = 1; i < makerOrders.length; i++) { if (makerOrders[i].isMakerBettingOutcomeOne != isMakerBettingOutcomeOne || makerOrders[i].marketHash != marketHash || makerOrders[i].baseToken != baseToken ) { return false; } } } return true; } /// @notice Settles multiple orders for the maker at once. /// @param makerOrders The orders to fill. /// @param takerAmounts The amount to fill for each order. /// @param taker The taker of these orders. /// @param fillHash The fill hash, if applicable in the case of a meta fill. function settleOrdersForMaker( LibOrder.Order[] memory makerOrders, uint256[] memory takerAmounts, address taker, bytes32 fillHash ) private { for (uint256 i = 0; i < makerOrders.length; i++) { LibOrderAmounts.OrderAmounts memory orderAmounts = LibOrderAmounts.computeOrderAmounts( makerOrders[i], takerAmounts[i] ); uint256 newFillAmount = fills.fill(makerOrders[i], orderAmounts.takerAmount); settleOrderForMaker( makerOrders[i], orderAmounts ); emit OrderFill( makerOrders[i].maker, makerOrders[i].marketHash, taker, newFillAmount, makerOrders[i].getOrderHash(), fillHash, makerOrders[i], orderAmounts ); } } }
pragma solidity 0.5.16; pragma experimental ABIEncoderV2; import "../interfaces/IAffiliateRegistry.sol"; import "../interfaces/permissions/IWhitelist.sol"; contract AffiliateRegistry is IAffiliateRegistry { uint256 public constant MAX_AFFILIATE_FEE = 3*(10**19); IWhitelist private systemParamsWhitelist; address private defaultAffiliate; mapping (address => address) private addressToAffiliate; mapping (address => uint256) private affiliateFeeFrac; event AffiliateSet( address member, address affiliate ); event AffiliateFeeFracSet( address affiliate, uint256 feeFrac ); constructor(IWhitelist _systemParamsWhitelist) public { systemParamsWhitelist = _systemParamsWhitelist; } /// @notice Throws if the caller is not a system params admin. modifier onlySystemParamsAdmin() { require( systemParamsWhitelist.getWhitelisted(msg.sender), "NOT_SYSTEM_PARAM_ADMIN" ); _; } /// @notice Sets the affiliate for an address. /// @param member The address to attach to the affiliate. /// @param affiliate The affiliate address to attach. function setAffiliate(address member, address affiliate) public onlySystemParamsAdmin { require( affiliate != address(0), "AFFILIATE_ZERO_ADDRESS" ); addressToAffiliate[member] = affiliate; } /// @notice Sets the affiliate fee fraction for an address. /// @param affiliate The affiliate whose fee fraction should be changed. /// @param feeFrac The new fee fraction for this affiliate. function setAffiliateFeeFrac(address affiliate, uint256 feeFrac) public onlySystemParamsAdmin { require( feeFrac < MAX_AFFILIATE_FEE, "AFFILIATE_FEE_TOO_HIGH" ); affiliateFeeFrac[affiliate] = feeFrac; } /// @notice Sets the default affiliate if no affiliate is set for an address. /// @param affiliate The new default affiliate. function setDefaultAffiliate(address affiliate) public onlySystemParamsAdmin { require( affiliate != address(0), "AFFILIATE_ZERO_ADDRESS" ); defaultAffiliate = affiliate; } /// @notice Gets the affiliate for an address. If no affiliate is set, it returns the /// default affiliate. /// @param member The address to query. /// @return The affiliate for this address. function getAffiliate(address member) public view returns (address) { address affiliate = addressToAffiliate[member]; if (affiliate == address(0)) { return defaultAffiliate; } else { return affiliate; } } function getAffiliateFeeFrac(address affiliate) public view returns (uint256) { return affiliateFeeFrac[affiliate]; } function getDefaultAffiliate() public view returns (address) { return defaultAffiliate; } }
pragma solidity 0.5.16; pragma experimental ABIEncoderV2; import "../libraries/LibOutcome.sol"; import "../libraries/LibOrder.sol"; import "../interfaces/trading/IFillOrder.sol"; import "../interfaces/trading/IFeeSchedule.sol"; import "../interfaces/ISystemParameters.sol"; import "../interfaces/IOutcomeReporter.sol"; import "../interfaces/IAffiliateRegistry.sol"; import "../interfaces/IEscrow.sol"; import "openzeppelin-solidity/contracts/math/SafeMath.sol"; import "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol"; /// @title Escrow /// @author Julian Wilson <[email protected]> /// @notice Central location that stores all escrow when /// swaps are traded. contract Escrow is IEscrow { using SafeMath for uint256; ISystemParameters private systemParameters; IFillOrder private fillOrder; IOutcomeReporter private outcomeReporter; IFeeSchedule private feeSchedule; IAffiliateRegistry private affiliateRegistry; // marketHash => baseToken => owner => side => amount mapping(bytes32 => mapping(address => mapping(address => mapping(uint8 => uint256)))) returnAmounts; mapping(bytes32 => mapping(address => mapping(address => mapping(uint8 => uint256)))) stakedAmounts; struct BetFee { uint256 oracleFee; uint256 affiliateFee; } event BetSettled( address indexed owner, bytes32 indexed marketHash, address indexed baseToken, LibOutcome.Outcome outcome, uint256 settledAmount, uint256 oracleFeeAmount, uint256 affiliateFeeAmount ); constructor( ISystemParameters _systemParameters, IFillOrder _fillOrder, IOutcomeReporter _outcomeReporter, IFeeSchedule _feeSchedule, IAffiliateRegistry _affiliateRegistry ) public { systemParameters = _systemParameters; fillOrder = _fillOrder; outcomeReporter = _outcomeReporter; feeSchedule = _feeSchedule; affiliateRegistry = _affiliateRegistry; } /// @notice Throws if the caller is not the FillOrder contract. modifier onlyFillOrder() { require(msg.sender == address(fillOrder), "ONLY_FILL_ORDER"); _; } /// @notice Throws if the market's tokens are not redeemable. /// @param marketHash The market to check. modifier marketTokensRedeemable(bytes32 marketHash) { require(isMarketRedeemable(marketHash), "INVALID_REDEMPTION_TIME"); _; } /// @notice Redeems outcome one or outcome two return amounts after a market /// has been resolved. /// @param owner The user to redeem for. /// @param marketHash The market that is resolved. /// @param baseTokenAddress The token to resolve. function settleBet( address owner, bytes32 marketHash, address baseTokenAddress ) public marketTokensRedeemable(marketHash) { IERC20 baseToken = IERC20(baseTokenAddress); LibOutcome.Outcome marketResult = outcomeReporter.getReportedOutcome( marketHash ); uint256 outcomeOneEligibility = returnAmounts[marketHash][baseTokenAddress][owner][uint8( LibOutcome.Outcome.OUTCOME_ONE )]; uint256 outcomeTwoEligibility = returnAmounts[marketHash][baseTokenAddress][owner][uint8( LibOutcome.Outcome.OUTCOME_TWO )]; uint256 outcomeOneStake = stakedAmounts[marketHash][baseTokenAddress][owner][uint8( LibOutcome.Outcome.OUTCOME_ONE )]; uint256 outcomeTwoStake = stakedAmounts[marketHash][baseTokenAddress][owner][uint8( LibOutcome.Outcome.OUTCOME_TWO )]; BetFee memory betFees; uint256 payout; if ( marketResult == LibOutcome.Outcome.OUTCOME_ONE && outcomeOneEligibility > 0 ) { uint256 profits = outcomeOneEligibility.sub(outcomeOneStake); betFees = settleFees(baseTokenAddress, owner, profits); payout = outcomeOneEligibility.sub(betFees.oracleFee).sub( betFees.affiliateFee ); returnAmounts[marketHash][baseTokenAddress][owner][uint8( LibOutcome.Outcome.OUTCOME_ONE )] = 0; } else if ( marketResult == LibOutcome.Outcome.OUTCOME_TWO && outcomeTwoEligibility > 0 ) { uint256 profits = outcomeTwoEligibility.sub(outcomeTwoStake); betFees = settleFees(baseTokenAddress, owner, profits); payout = outcomeTwoEligibility.sub(betFees.oracleFee).sub( betFees.affiliateFee ); returnAmounts[marketHash][baseTokenAddress][owner][uint8( LibOutcome.Outcome.OUTCOME_TWO )] = 0; } else if ( marketResult == LibOutcome.Outcome.VOID && (outcomeOneStake > 0 || outcomeTwoStake > 0) ) { if (outcomeOneStake > 0) { payout = outcomeOneStake; stakedAmounts[marketHash][baseTokenAddress][owner][uint8( LibOutcome.Outcome.OUTCOME_ONE )] = 0; } if (outcomeTwoStake > 0) { payout = payout.add(outcomeTwoStake); stakedAmounts[marketHash][baseTokenAddress][owner][uint8( LibOutcome.Outcome.OUTCOME_TWO )] = 0; } } else { revert("MARKET_WRONG_RESOLUTION"); } require(baseToken.transfer(owner, payout), "CANNOT_TRANSFER_ESCROW"); emit BetSettled( owner, marketHash, baseTokenAddress, marketResult, payout, betFees.oracleFee, betFees.affiliateFee ); } /// @notice Updates the user's escrowed amount they have in the market. /// @param marketHash The market to redeem. /// @param baseToken The token with which they are betting. /// @param user The user to update. /// @param outcome The side to update. /// @param amount The amount to add. function updateStakedAmount( bytes32 marketHash, address baseToken, address user, LibOutcome.Outcome outcome, uint256 amount ) public onlyFillOrder { stakedAmounts[marketHash][baseToken][user][uint8( outcome )] = stakedAmounts[marketHash][baseToken][user][uint8(outcome)].add( amount ); } /// @notice Updates the user's return amount /// @param marketHash The market for which they are betting on outcome one. /// @param baseToken The token with which they are betting. /// @param user The user to update. /// @param outcome The outcome to increase /// @param amount The amount to add. function increaseReturnAmount( bytes32 marketHash, address baseToken, address user, LibOutcome.Outcome outcome, uint256 amount ) public onlyFillOrder { returnAmounts[marketHash][baseToken][user][uint8( outcome )] = returnAmounts[marketHash][baseToken][user][uint8(outcome)].add( amount ); } /// @notice Checks if the market's tokens are redeemable. /// @param marketHash The market to check. /// @return true if the market's tokens are redeemable, false otherwise. function isMarketRedeemable(bytes32 marketHash) public view returns (bool) { uint256 reportTime = outcomeReporter.getReportTime(marketHash); if (reportTime > 0) { return now > reportTime; } else { return false; } } /// @notice Checks if the owner has a valid redeemable bet. /// @param owner The owner of the bet. /// @param marketHash The market to check. /// @param baseToken The base token to check. /// @return true if the owner has a valid redeemable bet for this market, false otherwise. function getEligibility( address owner, bytes32 marketHash, address baseToken ) public view returns (Eligibility memory eligibility) { if (!isMarketRedeemable(marketHash)) { return Eligibility({ hasEligibility: false, outcome: LibOutcome.Outcome.VOID, amount: 0 }); } LibOutcome.Outcome marketResult = outcomeReporter.getReportedOutcome( marketHash ); uint256 outcomeOneEligibility = returnAmounts[marketHash][baseToken][owner][uint8( LibOutcome.Outcome.OUTCOME_ONE )]; uint256 outcomeTwoEligibility = returnAmounts[marketHash][baseToken][owner][uint8( LibOutcome.Outcome.OUTCOME_TWO )]; uint256 outcomeOneStake = stakedAmounts[marketHash][baseToken][owner][uint8( LibOutcome.Outcome.OUTCOME_ONE )]; uint256 outcomeTwoStake = stakedAmounts[marketHash][baseToken][owner][uint8( LibOutcome.Outcome.OUTCOME_TWO )]; if ( marketResult == LibOutcome.Outcome.OUTCOME_ONE && outcomeOneEligibility > 0 ) { return Eligibility({ hasEligibility: true, outcome: LibOutcome.Outcome.OUTCOME_ONE, amount: outcomeOneEligibility }); } else if ( marketResult == LibOutcome.Outcome.OUTCOME_TWO && outcomeTwoEligibility > 0 ) { return Eligibility({ hasEligibility: true, outcome: LibOutcome.Outcome.OUTCOME_TWO, amount: outcomeTwoEligibility }); } else if ( marketResult == LibOutcome.Outcome.VOID && (outcomeOneStake > 0 || outcomeTwoStake > 0) ) { return Eligibility({ hasEligibility: true, outcome: LibOutcome.Outcome.VOID, amount: outcomeOneStake.add(outcomeTwoStake) }); } else { return Eligibility({ hasEligibility: false, outcome: LibOutcome.Outcome.VOID, amount: 0 }); } } function getReturnAmount( bytes32 marketHash, address baseToken, address owner, LibOutcome.Outcome outcome ) public view returns (uint256) { return returnAmounts[marketHash][baseToken][owner][uint8(outcome)]; } function getStakedAmount( bytes32 marketHash, address baseToken, address owner, LibOutcome.Outcome outcome ) public view returns (uint256) { return stakedAmounts[marketHash][baseToken][owner][uint8(outcome)]; } /// @notice Settles fees for an owner and for a market. /// @param baseToken The token to settle. /// @param owner The owner. /// @param profits How much profit the owner made off this bet. /// @return The fees that were settled. function settleFees(address baseToken, address owner, uint256 profits) private returns (BetFee memory) { address affiliate = affiliateRegistry.getAffiliate(owner); uint256 affiliateFeeFrac = affiliateRegistry.getAffiliateFeeFrac( affiliate ); uint256 oracleFee = settleOracleFee(baseToken, profits); uint256 affiliateFee = settleAffiliateFee( baseToken, profits, affiliate, affiliateFeeFrac ); return BetFee({oracleFee: oracleFee, affiliateFee: affiliateFee}); } /// @notice Settles the affiliate fee for a market. /// @param baseToken The token to settle. /// @param profits The profits made on the bet. /// @param affiliate The affiliate set for the winner of the bet. /// @param affiliateFeeFrac The fee assigned to this affiliate. /// @return The affiliate fee paid. function settleAffiliateFee( address baseToken, uint256 profits, address affiliate, uint256 affiliateFeeFrac ) private returns (uint256) { IERC20 token = IERC20(baseToken); uint256 affiliateFeeAmount = profits.mul(affiliateFeeFrac).div( LibOrder.getOddsPrecision() ); if (affiliateFeeAmount > 0) { require( token.transfer(affiliate, affiliateFeeAmount), "CANNOT_TRANSFER_AFFILIATE_FEE" ); } return affiliateFeeAmount; } /// @notice Calculates oracle fee to be paid based on the market profits /// @param baseToken The base token to settle. /// @param profits Profit of user's outcome eligibility. /// @return The amount oracle fee to be paid. function settleOracleFee(address baseToken, uint256 profits) private returns (uint256) { IERC20 token = IERC20(baseToken); uint256 oracleFee = feeSchedule.getOracleFees(baseToken); uint256 oracleFeeAmount = profits.mul(oracleFee).div( LibOrder.getOddsPrecision() ); address oracleFeeRecipient = systemParameters.getOracleFeeRecipient(); if (oracleFeeAmount > 0) { require( token.transfer(oracleFeeRecipient, oracleFeeAmount), "CANNOT_TRANSFER_FEE" ); } return oracleFeeAmount; } }
pragma solidity 0.5.16; contract Initializable { bool public initialized; /// @notice Throws if this contract has already been initialized. modifier notInitialized() { require(!initialized, "ALREADY_INITIALIZED"); _; } }
//solhint-disable pragma solidity 0.5.16; contract Migrations { address public owner; uint public last_completed_migration; constructor() public { owner = msg.sender; } modifier restricted() { if (msg.sender == owner) _; } function setCompleted(uint completed) public restricted { last_completed_migration = completed; } function upgrade(address new_address) public restricted { Migrations upgraded = Migrations(new_address); upgraded.setCompleted(last_completed_migration); } }
pragma solidity 0.5.16; pragma experimental ABIEncoderV2; import "../libraries/LibOutcome.sol"; import "../interfaces/IOutcomeReporter.sol"; import "../interfaces/permissions/IWhitelist.sol"; import "./Initializable.sol"; import "openzeppelin-solidity/contracts/math/SafeMath.sol"; /// @title OutcomeReporter /// @author Julian Wilson <[email protected]> /// @notice Allows OutcomeReporter admins to report an initial outcome on an event. contract OutcomeReporter is IOutcomeReporter { using SafeMath for uint256; IWhitelist private outcomeReporterWhitelist; mapping(bytes32 => LibOutcome.Outcome) private reportedOutcomes; mapping(bytes32 => uint256) private reportTime; event OutcomeReported(bytes32 marketHash, LibOutcome.Outcome outcome); constructor( IWhitelist _outcomeReporterWhitelist ) public { outcomeReporterWhitelist = _outcomeReporterWhitelist; } /// @notice Throws if the caller is not an Outcome Reporter admin. modifier onlyOutcomeReporterAdmin() { require( outcomeReporterWhitelist.getWhitelisted(msg.sender), "NOT_OUTCOME_REPORTER_ADMIN" ); _; } /// @notice Throws if the market is already reported /// @param marketHash The market to check. modifier notAlreadyReported(bytes32 marketHash) { require( reportTime[marketHash] == 0, "MARKET_ALREADY_REPORTED" ); _; } /// @notice Reports the initial outcome of the market. /// Only callable by OutcomeReporter admins. /// Can only be reported once. /// @param marketHash The market to report. /// @param reportedOutcome The outcome to report. function reportOutcome(bytes32 marketHash, LibOutcome.Outcome reportedOutcome) public onlyOutcomeReporterAdmin notAlreadyReported(marketHash) { reportedOutcomes[marketHash] = reportedOutcome; reportTime[marketHash] = now; emit OutcomeReported(marketHash, reportedOutcome); } /// @notice Reports the outcome for several markets. /// @param marketHashes The market hashes to report. /// @param outcomes The outcomes to report. function reportOutcomes( bytes32[] memory marketHashes, LibOutcome.Outcome[] memory outcomes ) public { uint256 marketHashesLength = marketHashes.length; for (uint256 i = 0; i < marketHashesLength; i++) { reportOutcome(marketHashes[i], outcomes[i]); } } function getReportedOutcome(bytes32 marketHash) public view returns (LibOutcome.Outcome) { return reportedOutcomes[marketHash]; } function getReportTime(bytes32 marketHash) public view returns (uint256) { return reportTime[marketHash]; } }
pragma solidity 0.5.16; pragma experimental ABIEncoderV2; import "../interfaces/permissions/IWhitelist.sol"; import "../interfaces/ISystemParameters.sol"; /// @title SystemParameters /// @author Julian Wilson <[email protected]> /// @notice Stores system parameters. contract SystemParameters is ISystemParameters { address private oracleFeeRecipient; IWhitelist private systemParamsWhitelist; constructor(IWhitelist _systemParamsWhitelist) public { systemParamsWhitelist = _systemParamsWhitelist; } /// @notice Throws if the caller is not a system params admin. modifier onlySystemParamsAdmin() { require( systemParamsWhitelist.getWhitelisted(msg.sender), "NOT_SYSTEM_PARAM_ADMIN" ); _; } /// @notice Sets the oracle fee recipient. Only callable by SystemParams admins. /// @param newOracleFeeRecipient The new oracle fee recipient address function setNewOracleFeeRecipient(address newOracleFeeRecipient) public onlySystemParamsAdmin { oracleFeeRecipient = newOracleFeeRecipient; } function getOracleFeeRecipient() public view returns (address) { return oracleFeeRecipient; } }
pragma solidity 0.5.16; pragma experimental ABIEncoderV2; import "../../libraries/LibOrderAmounts.sol"; import "../../libraries/LibString.sol"; import "../../libraries/LibOrder.sol"; import "../../interfaces/trading/IFeeSchedule.sol"; import "../../interfaces/trading/IFills.sol"; import "../../interfaces/trading/ITokenTransferProxy.sol"; import "../../interfaces/trading/IReadOnlyValidator.sol"; import "../../interfaces/IOutcomeReporter.sol"; import "../../interfaces/trading/IEIP712FillHasher.sol"; import "../../interfaces/extensions/IOrderValidator.sol"; import "openzeppelin-solidity/contracts/math/SafeMath.sol"; import "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol"; /// @title OrderValidator /// @author Julian Wilson <[email protected]> /// @notice Functions to validate orders off-chain and /// return a user-friendly string. /// None of these are used in the actual protocol to determine /// any state changes. contract OrderValidator is IOrderValidator { using LibOrder for LibOrder.Order; using LibString for string; using SafeMath for uint256; ITokenTransferProxy private proxy; IFills private fills; IFeeSchedule private feeSchedule; IEIP712FillHasher private eip712FillHasher; IOutcomeReporter private outcomeReporter; constructor( ITokenTransferProxy _proxy, IFills _fills, IFeeSchedule _feeSchedule, IEIP712FillHasher _eip712FillHasher, IOutcomeReporter _outcomeReporter ) public { proxy = _proxy; fills = _fills; feeSchedule = _feeSchedule; eip712FillHasher = _eip712FillHasher; outcomeReporter = _outcomeReporter; } /// @notice Gets the current status of an order without considering /// any individual taker. /// @param order The order to examine. /// @param makerSig The signature of maker on this order. /// @return A string representing the status. "OK" for valid. function getOrderStatus( LibOrder.Order memory order, bytes memory makerSig ) public view returns (string memory) { string memory baseMakerOrderStatus = getBaseOrderStatus( order, makerSig ); if (!baseMakerOrderStatus.equals("OK")) {return baseMakerOrderStatus;} uint256 remainingSpace = fills.remainingSpace(order); if (remainingSpace == 0) { return "FULLY_FILLED"; } LibOrderAmounts.OrderAmounts memory orderAmounts = LibOrderAmounts.computeOrderAmounts( order, remainingSpace ); string memory allowanceBalanceValidity = getMakerAllowanceAndBalanceStatus( orderAmounts, order.baseToken, order.maker ); return allowanceBalanceValidity; } /// @notice Gets the current status of multiple orders without considering /// any individual taker. /// @param orders The orders to examine. /// @param makerSigs The signature of the makers on this order. /// @return A string representing the status. "OK" for valid. function getMultiOrderStatus( LibOrder.Order[] memory orders, bytes[] memory makerSigs ) public view returns (string[] memory) { string[] memory statuses = new string[](orders.length); for (uint256 i = 0; i < orders.length; i++) { statuses[i] = getOrderStatus( orders[i], makerSigs[i] ); } return statuses; } /// @notice Gets the status of a multi-order fill /// @param fillDetails The fills to execute /// @param executorSig The signature of the executor, if any. /// @param taker The hypothetical taker. /// @return A string representing the status. "OK" for valid. function getFillStatus( LibOrder.FillDetails memory fillDetails, bytes memory executorSig, address taker ) public view returns (string memory) { address executor = fillDetails.fills.orders[0].executor; if (executor != address(0)) { bytes32 fillHash = eip712FillHasher.getDetailsHash(fillDetails); if (fills.getFillHashSubmitted(fillHash)) { return "FILL_ALREADY_SUBMITTED"; } if (ECDSA.recover(fillHash, executorSig) != executor) { return "EXECUTOR_SIGNATURE_MISMATCH"; } } if (fillDetails.fills.orders.length > 1) { for (uint256 i = 1; i < fillDetails.fills.orders.length; i++) { if (fillDetails.fills.orders[i].executor != executor) { return "INCONSISTENT_EXECUTORS"; } } } return _getFillStatus( fillDetails.fills.orders, taker, fillDetails.fills.takerAmounts, fillDetails.fills.makerSigs ); } /// @notice Gets the status of a meta multi-order fill /// @param fillDetails The fills to execute, meta style. /// @param taker The hypothetical taker. /// @param takerSig The taker's signature for this fill. /// @param executorSig The signature of the executor, if any. /// @return A string representing the status. "OK" for valid. function getMetaFillStatus( LibOrder.FillDetails memory fillDetails, address taker, bytes memory takerSig, bytes memory executorSig ) public view returns (string memory) { bytes32 fillHash = eip712FillHasher.getDetailsHash(fillDetails); if (ECDSA.recover(fillHash, takerSig) != taker) { return "TAKER_SIGNATURE_MISMATCH"; } if (fills.getFillHashSubmitted(fillHash)) { return "FILL_ALREADY_SUBMITTED"; } address executor = fillDetails.fills.orders[0].executor; if (executor != address(0) && ECDSA.recover(fillHash, executorSig) != executor) { return "EXECUTOR_SIGNATURE_MISMATCH"; } if (fillDetails.fills.orders.length > 1) { for (uint256 i = 1; i < fillDetails.fills.orders.length; i++) { if (fillDetails.fills.orders[i].executor != executor) { return "INCONSISTENT_EXECUTORS"; } } } return _getFillStatus( fillDetails.fills.orders, taker, fillDetails.fills.takerAmounts, fillDetails.fills.makerSigs ); } /// @notice Gets the combined status of several orders considering /// a single taker and a taker amount for each order. /// @param makerOrders The orders to fill. /// @param taker The hypothetical taker. /// @param takerAmounts The hypothetical amounts to fill. /// @param makerSigs The signatures of the makers on these orders. /// @return A string representing the status. "OK" for valid. function _getFillStatus( LibOrder.Order[] memory makerOrders, address taker, uint256[] memory takerAmounts, bytes[] memory makerSigs ) private view returns (string memory) { string memory baseMultiFillStatus = getBaseMultiFillStatus( makerOrders, taker, takerAmounts, makerSigs ); if (!baseMultiFillStatus.equals("OK")) { return baseMultiFillStatus; } return getMultiAllowanceBalanceStatus( makerOrders, takerAmounts, taker ); } /// @notice Gets the "base" status of an order without considering any token /// allowances and balances. /// @param order A maker order. /// @param makerSig The signature of the maker on this order. /// @return A string representing the status. "OK" for valid. function getBaseOrderStatus( LibOrder.Order memory order, bytes memory makerSig ) private view returns (string memory) { string memory paramValidity = order.getParamValidity(); if (paramValidity.equals("OK") == false) {return paramValidity;} if (outcomeReporter.getReportTime(order.marketHash) != 0) { return "MARKET_NOT_TRADEABLE"; } if (order.checkSignature(makerSig) == false) { return "BAD_SIGNATURE"; } if (fills.isOrderCancelled(order)) { return "CANCELLED"; } return "OK"; } /// @notice Checks the maker's balances and allowances for given order amounts /// @param orderAmounts The computed balances to transfer as a result of the fill. /// @param baseTokenAddress The base token to use. /// @param maker The maker's balance to check. /// @return A string representing the status. "OK" for valid. function getMakerAllowanceAndBalanceStatus( LibOrderAmounts.OrderAmounts memory orderAmounts, address baseTokenAddress, address maker ) private view returns (string memory) { IERC20 baseToken = IERC20(baseTokenAddress); if (baseToken.balanceOf(maker) < orderAmounts.takerAmount) { return "MAKER_INSUFFICIENT_BASE_TOKEN"; } if (baseToken.allowance(maker, address(proxy)) < orderAmounts.takerAmount) { return "MAKER_INSUFFICIENT_BASE_TOKEN_ALLOWANCE"; } return "OK"; } /// @notice Gets the status in terms of token balances /// and allowances if several orders were to be filled by a /// single taker. /// /// For this method, we can combine the orders and treat it as /// one big order for the taker, but still need to check each /// order individually for makers. /// /// Assumes base token is same for every order. /// @param makerOrders The hypothetical orders to fill. /// @param takerAmounts The hypothetical amounts to fill for each order. /// @param taker The taker filling these orders. /// @return A string representing the status. "OK" for valid. function getMultiAllowanceBalanceStatus( LibOrder.Order[] memory makerOrders, uint256[] memory takerAmounts, address taker ) private view returns (string memory) { address baseToken = makerOrders[0].baseToken; LibOrderAmounts.OrderAmounts memory totalOrderAmounts = LibOrderAmounts.computeTotalOrderAmounts( makerOrders, takerAmounts ); for (uint256 i = 0; i < makerOrders.length; i++) { LibOrderAmounts.OrderAmounts memory individualOrderAmounts = LibOrderAmounts.computeOrderAmounts( makerOrders[i], takerAmounts[i] ); string memory makerAllowanceBalanceValidity = getMakerAllowanceAndBalanceStatus( individualOrderAmounts, baseToken, makerOrders[i].maker ); if (!makerAllowanceBalanceValidity.equals("OK")) { return makerAllowanceBalanceValidity; } } return getTakerAllowanceAndBalanceStatus( totalOrderAmounts, baseToken, taker ); } /// @notice Gets the combined base status of several orders considering /// a single taker and a taker amount for each order. /// Does not consider balances or allowances. /// The markets must be identical in order to combine taker amounts. /// @param makerOrders The orders to fill. /// @param taker The hypothetical taker. /// @param takerAmounts The hypothetical amounts to fill. /// @param signatures The signatures of the makers on these orders. /// @return A string representing the status. "OK" for valid. function getBaseMultiFillStatus( LibOrder.Order[] memory makerOrders, address taker, uint256[] memory takerAmounts, bytes[] memory signatures ) private view returns (string memory) { for (uint256 i = 0; i < makerOrders.length; i++) { if (makerOrders[i].marketHash != makerOrders[0].marketHash) {return "MARKETS_NOT_IDENTICAL";} if (makerOrders[i].baseToken != makerOrders[0].baseToken) {return "BASE_TOKENS_NOT_IDENTICAL";} // Don't have to compare directions - all that matters is the amount end of the day string memory baseMakerOrderStatus = getBaseFillStatus( makerOrders[i], signatures[i], takerAmounts[i], taker ); if (!baseMakerOrderStatus.equals("OK")) {return baseMakerOrderStatus;} } return "OK"; } /// @notice Checks the fillability of an order along with the taker amount. /// Does not check balances. /// @param order The order to fill. /// @param makerSig The maker's signature. /// @param takerAmount The hypothetical taker amount. /// @param taker The taker. /// @return A string representing the status. "OK" for valid. function getBaseFillStatus( LibOrder.Order memory order, bytes memory makerSig, uint256 takerAmount, address taker ) private view returns (string memory) { if (takerAmount == 0) {return "TAKER_AMOUNT_NOT_POSITIVE";} string memory baseMakerOrderStatus = getBaseOrderStatus( order, makerSig ); if (!baseMakerOrderStatus.equals("OK")) {return baseMakerOrderStatus;} if (taker == order.maker) {return "TAKER_NOT_MAKER";} if (!fills.orderHasSpace(order, takerAmount)) {return "INSUFFICIENT_SPACE";} return "OK"; } /// @notice Checks the taker's balances and allowances for a given order to be filled. /// @param orderAmounts The computed balances to transfer as a result of the fill. /// @param baseTokenAddress The base token address /// @param taker The hypothetical taker. /// @return A string representing the status. "OK" for valid. function getTakerAllowanceAndBalanceStatus( LibOrderAmounts.OrderAmounts memory orderAmounts, address baseTokenAddress, address taker ) private view returns (string memory) { IERC20 baseToken = IERC20(baseTokenAddress); if (baseToken.balanceOf(taker) < orderAmounts.takerEscrow) { return "TAKER_INSUFFICIENT_BASE_TOKEN"; } if (baseToken.allowance(taker, address(proxy)) < orderAmounts.takerEscrow) { return "TAKER_INSUFFICIENT_BASE_TOKEN_ALLOWANCE"; } return "OK"; } }
pragma solidity 0.5.16; pragma experimental ABIEncoderV2; import "./Whitelist.sol"; import "../../interfaces/permissions/ISuperAdminRole.sol"; /// @title OutcomeReporterWhitelist /// @author Julian Wilson <[email protected]> /// @notice A whitelist that represents all members allowed to /// report on markets in the protocol. contract OutcomeReporterWhitelist is Whitelist { constructor(ISuperAdminRole _superAdminRole) public Whitelist(_superAdminRole) {} }
pragma solidity 0.5.16; pragma experimental ABIEncoderV2; import "../../interfaces/permissions/ISuperAdminRole.sol"; import "openzeppelin-solidity/contracts/access/Roles.sol"; import "openzeppelin-solidity/contracts/math/SafeMath.sol"; /// @title SuperAdminRole /// @author Julian Wilson <[email protected]> /// @notice This is copied from the [email protected] library CapperRole and just /// renamed to SuperAdminRole. Super admins are parents to all other admins in the system. /// Super admins can also promote others to super admins but not remove them. contract SuperAdminRole is ISuperAdminRole { using Roles for Roles.Role; using SafeMath for uint256; event SuperAdminAdded(address indexed account); event SuperAdminRemoved(address indexed account); Roles.Role private superAdmins; uint256 private superAdminCount; constructor() public { _addSuperAdmin(msg.sender); } /// @notice Throws if the caller is not a super admin./ modifier onlySuperAdmin() { require(isSuperAdmin(msg.sender), "NOT_SUPER_ADMIN"); _; } /// @notice Adds a super admin to the list. /// @param account The account to add. function addSuperAdmin(address account) public onlySuperAdmin { _addSuperAdmin(account); } /// @notice Throws if the caller is last super admin left modifier atLeastOneSuperAdmin() { require( superAdminCount > 1, "LAST_SUPER_ADMIN" ); _; } /// @notice Removes a super admin from the list. /// @param account The account to add. function removeSuperAdmin(address account) public onlySuperAdmin atLeastOneSuperAdmin { _removeSuperAdmin(account); } /// @notice Internal function to add an account to the super admin list. /// @param account The account to add. function _addSuperAdmin(address account) internal { superAdmins.add(account); superAdminCount = superAdminCount.add(1); emit SuperAdminAdded(account); } /// @notice Internal function to remove an account from the super admin list. /// @param account The account to remove. function _removeSuperAdmin(address account) internal { superAdmins.remove(account); superAdminCount = superAdminCount.sub(1); emit SuperAdminRemoved(account); } /// @notice Gets the total number of super admins. /// @return The total number of super admins. function getSuperAdminCount() public view returns (uint256) { return superAdminCount; } /// @notice Checks if an account is a super admin. /// @param account The account to add. /// @return true if the account is a super admin, false otherwise. function isSuperAdmin(address account) public view returns (bool) { return superAdmins.has(account); } }
pragma solidity 0.5.16; pragma experimental ABIEncoderV2; import "../../interfaces/permissions/ISuperAdminRole.sol"; import "./Whitelist.sol"; /// @title OutcomeReporterWhitelist /// @author Julian Wilson <[email protected]> /// @notice A whitelist that represents all members allowed to /// change parameters in the protocol. contract SystemParamsWhitelist is Whitelist { constructor(ISuperAdminRole _superAdminRole) public Whitelist(_superAdminRole) {} }
pragma solidity 0.5.16; pragma experimental ABIEncoderV2; import "../../interfaces/permissions/ISuperAdminRole.sol"; import "../../interfaces/permissions/IWhitelist.sol"; /// @title Whitelist /// @author Julian Wilson <[email protected]> /// @notice The Whitelist contract has a whitelist of addresses, and provides basic authorization control functions. /// This simplifies the implementation of "user permissions". /// This Whitelist is special in that only super admins can add others to this whitelist. /// This is copied verbatim, plus the SuperAdminRole authorization, from openzeppelin. contract Whitelist is IWhitelist { ISuperAdminRole internal superAdminRole; mapping (address => bool) public whitelisted; constructor(ISuperAdminRole _superAdminRole) public { superAdminRole = _superAdminRole; } /// @notice Throws if the operator is not a super admin. /// @param operator The operator. modifier onlySuperAdmin(address operator) { require( superAdminRole.isSuperAdmin(operator), "NOT_A_SUPER_ADMIN" ); _; } /// @notice Adds an operator to the whitelist /// Only callable by the SuperAdmin role. /// @param operator The operator to add. function addAddressToWhitelist(address operator) public onlySuperAdmin(msg.sender) { whitelisted[operator] = true; } /// @notice Removes an address from the whitelist /// Only callable by the SuperAdmin role. /// @param operator The operator to remove. function removeAddressFromWhitelist(address operator) public onlySuperAdmin(msg.sender) { whitelisted[operator] = false; } /// @notice Checks if the operator is whitelisted. /// @param operator The operator. /// @return true if the operator is whitelisted, false otherwise function getWhitelisted(address operator) public view returns (bool) { return whitelisted[operator]; } }
pragma solidity 0.5.16; /* solium-disable */ contract DAI { // --- ERC20 Data --- string public constant name = "Dai Stablecoin"; string public constant symbol = "DAI"; string public constant version = "1"; uint8 public constant decimals = 18; uint256 public totalSupply; mapping (address => uint) public balanceOf; mapping (address => mapping (address => uint)) public allowance; mapping (address => uint) public nonces; event Approval(address indexed src, address indexed guy, uint wad); event Transfer(address indexed src, address indexed dst, uint wad); // --- Math --- function add(uint x, uint y) internal pure returns (uint z) { require((z = x + y) >= x); } function sub(uint x, uint y) internal pure returns (uint z) { require((z = x - y) <= x); } // --- EIP712 niceties --- bytes32 public DOMAIN_SEPARATOR; // bytes32 public constant PERMIT_TYPEHASH = keccak256("Permit(address holder,address spender,uint256 nonce,uint256 expiry,bool allowed)"); bytes32 public constant PERMIT_TYPEHASH = 0xea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb; constructor(uint256 chainId_) public { DOMAIN_SEPARATOR = keccak256(abi.encode( keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), keccak256(bytes(name)), keccak256(bytes(version)), chainId_, address(this) )); } // --- Token --- function transfer(address dst, uint wad) external returns (bool) { return transferFrom(msg.sender, dst, wad); } function transferFrom(address src, address dst, uint wad) public returns (bool) { require(balanceOf[src] >= wad, "Dai/insufficient-balance"); if (src != msg.sender && allowance[src][msg.sender] != uint(-1)) { require(allowance[src][msg.sender] >= wad, "Dai/insufficient-allowance"); allowance[src][msg.sender] = sub(allowance[src][msg.sender], wad); } balanceOf[src] = sub(balanceOf[src], wad); balanceOf[dst] = add(balanceOf[dst], wad); emit Transfer(src, dst, wad); return true; } function burn(address usr, uint wad) external { require(balanceOf[usr] >= wad, "Dai/insufficient-balance"); if (usr != msg.sender && allowance[usr][msg.sender] != uint(-1)) { require(allowance[usr][msg.sender] >= wad, "Dai/insufficient-allowance"); allowance[usr][msg.sender] = sub(allowance[usr][msg.sender], wad); } balanceOf[usr] = sub(balanceOf[usr], wad); totalSupply = sub(totalSupply, wad); emit Transfer(usr, address(0), wad); } function approve(address usr, uint wad) external returns (bool) { allowance[msg.sender][usr] = wad; emit Approval(msg.sender, usr, wad); return true; } function setBalance(address _target, uint256 _value) external { balanceOf[_target] = _value; } // --- Approve by signature --- function permit(address holder, address spender, uint256 nonce, uint256 expiry, bool allowed, uint8 v, bytes32 r, bytes32 s) external { bytes32 digest = keccak256(abi.encodePacked( "\x19\x01", DOMAIN_SEPARATOR, keccak256(abi.encode(PERMIT_TYPEHASH, holder, spender, nonce, expiry, allowed)) )); require(holder != address(0), "Dai/invalid-address-0"); require(holder == ecrecover(digest, v, r, s), "Dai/invalid-permit"); require(expiry == 0 || now <= expiry, "Dai/permit-expired"); require(nonce == nonces[holder]++, "Dai/invalid-nonce"); uint wad = allowed ? uint(-1) : 0; allowance[holder][spender] = wad; emit Approval(holder, spender, wad); } }
pragma solidity 0.5.16; pragma experimental ABIEncoderV2; /// @title DetailedToken /// @author Julian Wilson <[email protected]> /// @notice A utility contract to help pull name, symbol and decimals /// from ERC20 tokens. /// Verbatim, this: /// https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/token/ERC20/ERC20Detailed.sol contract DetailedToken { string private _name; string private _symbol; uint8 private _decimals; constructor (string memory name, string memory symbol, uint8 decimals) public { _name = name; _symbol = symbol; _decimals = decimals; } /// @notice Gets the name of the token. /// @return The name of the token. function name() public view returns (string memory) { return _name; } /// @notice Gets the symbol of the token. /// @return The symbol of the token. function symbol() public view returns (string memory) { return _symbol; } /// @notice Gets the decimals of the token. /// @return The decimals of the token. function decimals() public view returns (uint8) { return _decimals; } }
pragma solidity 0.5.16; import "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol"; import "openzeppelin-solidity/contracts/math/SafeMath.sol"; contract WETH is IERC20 { using SafeMath for uint256; string public constant name = "SportX WETH"; string public constant symbol = "WETH"; string public constant version = "1"; uint8 public constant decimals = 18; bytes2 constant private EIP191_HEADER = 0x1901; bytes32 public constant EIP712_UNWRAP_TYPEHASH = keccak256("Unwrap(address holder,uint256 amount,uint256 nonce,uint256 expiry)"); bytes32 public constant EIP712_PERMIT_TYPEHASH = keccak256( "Permit(address holder,address spender,uint256 nonce,uint256 expiry,bool allowed)" ); bytes32 public EIP712_DOMAIN_SEPARATOR; uint256 private _totalSupply; address public defaultOperator; address public defaultOperatorController; mapping (address => uint256) private _balances; mapping (address => mapping (address => uint256)) private _allowed; mapping (address => uint256) public unwrapNonces; mapping (address => uint256) public permitNonces; event Deposit(address indexed dst, uint256 amount); event Withdrawal(address indexed src, uint256 amount); constructor (address _operator, uint256 _chainId, address _defaultOperatorController) public { defaultOperator = _operator; defaultOperatorController = _defaultOperatorController; EIP712_DOMAIN_SEPARATOR = keccak256( abi.encode( keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), keccak256(bytes(name)), keccak256(bytes(version)), _chainId, address(this) ) ); } modifier onlyDefaultOperatorController() { require( msg.sender == defaultOperatorController, "ONLY_DEFAULT_OPERATOR_CONTROLLER" ); _; } /** * @dev Alias for the deposit function to deposit ETH. */ function() external payable { _deposit(msg.sender, msg.value); } /** * @dev Sets the default operator. Only callable by the default operator controller. * @param newDefaultOperator The new default operator. */ function setDefaultOperator(address newDefaultOperator) external onlyDefaultOperatorController { defaultOperator = newDefaultOperator; } /** * @dev Unwraps ETH meta style. Exchanges this token, WETH, for ETH 1 to 1 * @param holder The holder of WETH that wishes to withdraw. * @param amount The amount to withdraw. * @param nonce The current nonce for this holder, to prevent replays of the withdraw. * @param expiry The time after which this meta withdraw is not valid. * @param v v parameter in the ECDSA signature. * @param r r parameter in the ECDSA signature. * @param s s parameter in the ECDSA signature. */ function metaWithdraw( address payable holder, uint256 amount, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s ) external { bytes32 digest = keccak256( abi.encodePacked( EIP191_HEADER, EIP712_DOMAIN_SEPARATOR, keccak256( abi.encode( EIP712_UNWRAP_TYPEHASH, holder, amount, nonce, expiry ) ) ) ); require(holder != address(0), "INVALID_HOLDER"); require(holder == ecrecover(digest, v, r, s), "INVALID_SIGNATURE"); require(expiry == 0 || now <= expiry, "META_WITHDRAW_EXPIRED"); require(nonce == unwrapNonces[holder]++, "INVALID_NONCE"); require(_balances[holder] >= amount, "INSUFFICIENT_BALANCE"); _withdraw(holder, amount); } /** * @dev Meta approval for max funds. * @param holder The holder of the WETH that wishes to approve another account. * @param spender The designated spender of the WETH. * @param nonce The current permit nonce for this holder, to prevent replays of the increased allowance. * @param expiry The time after which this meta approval is not valid. * @param allowed true if this spender should be allowed to spend all funds on behalf of the holder, false otherwise. * @param v v parameter in the ECDSA signature. * @param r r parameter in the ECDSA signature. * @param s s parameter in the ECDSA signature. */ function permit( address holder, address spender, uint256 nonce, uint256 expiry, bool allowed, uint8 v, bytes32 r, bytes32 s ) external { bytes32 digest = keccak256( abi.encodePacked( "\x19\x01", EIP712_DOMAIN_SEPARATOR, keccak256( abi.encode( EIP712_PERMIT_TYPEHASH, holder, spender, nonce, expiry, allowed ) ) ) ); require(holder != address(0), "INVALID_HOLDER"); require(holder == ecrecover(digest, v, r, s), "INVALID_SIGNATURE"); require(expiry == 0 || now <= expiry, "PERMIT_EXPIRED"); require(nonce == permitNonces[holder]++, "INVALID_NONCE"); uint256 wad = allowed ? uint256(-1) : 0; _allowed[holder][spender] = wad; emit Approval(holder, spender, wad); } /** * @dev Total number of tokens in existence */ function totalSupply() public view returns (uint256) { return _totalSupply; } /** * @dev Gets the balance of the specified address. * @param owner The address to query the balance of. * @return An uint256 representing the amount owned by the passed address. */ function balanceOf(address owner) public view 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 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 returns (bool) { _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 returns (bool) { require(spender != address(0), "SPENDER_INVALID"); _allowed[msg.sender][spender] = value; emit Approval(msg.sender, spender, value); return true; } /** * @dev Transfer tokens from one address to another. * Note that while this function emits an Approval event, this is not required as per the specification, * and other compliant implementations may not emit the event. * @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 returns (bool) { _allowed[from][msg.sender] = _allowed[from][msg.sender].sub(value); _transfer(from, to, value); emit Approval(from, msg.sender, _allowed[from][msg.sender]); 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 * Emits an Approval event. * @param spender The address which will spend the funds. * @param addedValue The amount of tokens to increase the allowance by. */ function increaseAllowance(address spender, uint256 addedValue) public returns (bool) { require(spender != address(0), "SPENDER_INVALID"); _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 * Emits an Approval event. * @param spender The address which will spend the funds. * @param subtractedValue The amount of tokens to decrease the allowance by. */ function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) { require(spender != address(0), "SPENDER_INVALID"); _allowed[msg.sender][spender] = _allowed[msg.sender][spender].sub(subtractedValue); emit Approval(msg.sender, spender, _allowed[msg.sender][spender]); return true; } /** * @dev Unwraps ETH - exchanges this token, WETH, for ETH 1 to 1 * @param amount The amount of token to withdraw. */ function withdraw(uint256 amount) public { require(_balances[msg.sender] >= amount, "INSUFFICIENT_BALANCE"); _withdraw(msg.sender, amount); } /** * @dev Transfer token for a specified addresses * @param from The address to transfer from. * @param to The address to transfer to. * @param value The amount to be transferred. */ function _transfer(address from, address to, uint256 value) private { require(to != address(0), "SPENDER_INVALID"); _balances[from] = _balances[from].sub(value); _balances[to] = _balances[to].add(value); emit Transfer(from, to, value); } /** * @dev Internal function that unwraps ETH - exchanges this token, WETH, for ETH 1 to 1. * @param holder The holder that wishes to withdraw to ETH. * @param amount The amount of token to withdraw. */ function _withdraw(address payable holder, uint256 amount) private { _balances[holder] = _balances[holder].sub(amount); holder.transfer(amount); emit Withdrawal(holder, amount); } /** * @dev Wraps ETH - exchanges ETH for this token, WETH, 1 to 1 * Additionally auto approves the defaultOperator for this token to the max amount if it is zero. */ function _deposit(address sender, uint256 amount) private { _balances[sender] = _balances[sender].add(amount); uint256 senderAllowance = _allowed[sender][defaultOperator]; if (senderAllowance == 0) { _allowed[sender][defaultOperator] = uint256(-1); } emit Deposit(sender, amount); } }
pragma solidity 0.5.16; pragma experimental ABIEncoderV2; import "../../libraries/LibOrder.sol"; import "../../libraries/LibOrderAmounts.sol"; import "../../libraries/LibOutcome.sol"; import "../../interfaces/IEscrow.sol"; import "../../interfaces/IOutcomeReporter.sol"; import "../../interfaces/permissions/ISuperAdminRole.sol"; import "../../interfaces/trading/ITokenTransferProxy.sol"; import "../../interfaces/trading/IFills.sol"; import "../Initializable.sol"; import "openzeppelin-solidity/contracts/math/SafeMath.sol"; /// @title BaseFillOrder /// @author Julian Wilson <[email protected]> /// @notice Manages the core internal functionality to fill orders and check their validity. contract BaseFillOrder is Initializable { using LibOrder for LibOrder.Order; using SafeMath for uint256; ITokenTransferProxy internal proxy; IFills internal fills; IEscrow internal escrow; ISuperAdminRole internal superAdminRole; IOutcomeReporter internal outcomeReporter; event OrderFill( address indexed maker, bytes32 indexed marketHash, address indexed taker, uint256 newFilledAmount, bytes32 orderHash, bytes32 fillHash, LibOrder.Order order, LibOrderAmounts.OrderAmounts orderAmounts ); constructor(ISuperAdminRole _superAdminRole) public Initializable() { superAdminRole = _superAdminRole; } /// @notice Initializes this contract with reference to other contracts. /// @param _fills The Fills contract. /// @param _escrow The Escrow contract. /// @param _tokenTransferProxy The TokenTransferProxy contract. function initialize( IFills _fills, IEscrow _escrow, ITokenTransferProxy _tokenTransferProxy, IOutcomeReporter _outcomeReporter ) external notInitialized onlySuperAdmin(msg.sender) { fills = _fills; escrow = _escrow; proxy = _tokenTransferProxy; outcomeReporter = _outcomeReporter; initialized = true; } /// @notice Throws if the caller is not a super admin. /// @param operator The caller of the method. modifier onlySuperAdmin(address operator) { require( superAdminRole.isSuperAdmin(operator), "NOT_A_SUPER_ADMIN" ); _; } /// @notice Intermediate function to fill a single order /// @param order The order to be filled. /// @param takerAmount The amount to fill the order by. /// @param taker The taker of this order. /// @param fillHash The fill hash, if applicable. function _fillSingleOrder( LibOrder.Order memory order, uint256 takerAmount, address taker, bytes32 fillHash ) internal { LibOrderAmounts.OrderAmounts memory orderAmounts = LibOrderAmounts.computeOrderAmounts( order, takerAmount ); updateOrderState( order, orderAmounts, taker, fillHash ); } /// @notice Intermediate function that settles the order for each maker and taker. /// @param order The order that is being filled. /// @param orderAmounts The resulting order amounts given the taker amount. /// @param taker The taker of this order. /// @param fillHash The fill hash, if applicable in the case of a meta fill. function updateOrderState( LibOrder.Order memory order, LibOrderAmounts.OrderAmounts memory orderAmounts, address taker, bytes32 fillHash ) internal { uint256 newFillAmount = fills.fill(order, orderAmounts.takerAmount); settleOrderForMaker( order, orderAmounts ); settleOrderForTaker( order, orderAmounts, taker ); emit OrderFill( order.maker, order.marketHash, taker, newFillAmount, order.getOrderHash(), fillHash, order, orderAmounts ); } /// @notice Intermediate function that settles the order for the maker. /// @param order The order that is being filled. /// @param orderAmounts The resulting order amounts given the taker amount. function settleOrderForMaker( LibOrder.Order memory order, LibOrderAmounts.OrderAmounts memory orderAmounts ) internal { updateMakerEligibility( order, orderAmounts ); settleTransfersForMaker( order, orderAmounts ); } /// @notice Intermediate function that settles the order for the taker. /// @param order The order that is being filled. /// @param orderAmounts The resulting order amounts given the taker amount. /// @param taker The taker for this order. function settleOrderForTaker( LibOrder.Order memory order, LibOrderAmounts.OrderAmounts memory orderAmounts, address taker ) internal { updateTakerEligibility( order, orderAmounts, taker ); settleTransfersForTaker( order, orderAmounts, taker ); } /// @notice Checks that the order is valid given the taker and taker amount. /// @param order The order to check. /// @param takerAmount The amount the order will be filled by. /// @param taker The taker who would fill this order. /// @param makerSig The maker signature for this order. function assertOrderValid( LibOrder.Order memory order, uint256 takerAmount, address taker, bytes memory makerSig ) internal view { require( takerAmount > 0, "TAKER_AMOUNT_NOT_POSITIVE" ); order.assertValidAsTaker(taker, makerSig); require( outcomeReporter.getReportTime(order.marketHash) == 0, "MARKET_NOT_TRADEABLE" ); require( fills.orderHasSpace(order, takerAmount), "INSUFFICIENT_SPACE" ); } /// @notice Transfers a token using TokenTransferProxy transferFrom function. /// @param token Address of token to transferFrom. /// @param from Address transfering token. /// @param to Address receiving token. /// @param value Amount of token to transfer. /// @return Success of token transfer. function transferViaProxy( address token, address from, address to, uint256 value ) internal returns (bool) { return proxy.transferFrom(token, from, to, value); } /// @notice Updates the taker's eligibility for if they win the bet or tie. /// @param order The order that is being filled. /// @param orderAmounts The order amounts for this order. /// @param taker The taker of this order. function updateTakerEligibility( LibOrder.Order memory order, LibOrderAmounts.OrderAmounts memory orderAmounts, address taker ) private { if (order.isMakerBettingOutcomeOne) { escrow.increaseReturnAmount( order.marketHash, order.baseToken, taker, LibOutcome.Outcome.OUTCOME_TWO, orderAmounts.potSize ); escrow.updateStakedAmount( order.marketHash, order.baseToken, taker, LibOutcome.Outcome.OUTCOME_TWO, orderAmounts.takerEscrow ); } else { escrow.increaseReturnAmount( order.marketHash, order.baseToken, taker, LibOutcome.Outcome.OUTCOME_ONE, orderAmounts.potSize ); escrow.updateStakedAmount( order.marketHash, order.baseToken, taker, LibOutcome.Outcome.OUTCOME_ONE, orderAmounts.takerEscrow ); } } /// @notice Updates the maker's eligibility for if they win the bet or tie. /// @param order The order that is being filled. /// @param orderAmounts The order amounts for this order. function updateMakerEligibility( LibOrder.Order memory order, LibOrderAmounts.OrderAmounts memory orderAmounts ) private { if (order.isMakerBettingOutcomeOne) { escrow.increaseReturnAmount( order.marketHash, order.baseToken, order.maker, LibOutcome.Outcome.OUTCOME_ONE, orderAmounts.potSize ); escrow.updateStakedAmount( order.marketHash, order.baseToken, order.maker, LibOutcome.Outcome.OUTCOME_ONE, orderAmounts.takerAmount ); } else { escrow.increaseReturnAmount( order.marketHash, order.baseToken, order.maker, LibOutcome.Outcome.OUTCOME_TWO, orderAmounts.potSize ); escrow.updateStakedAmount( order.marketHash, order.baseToken, order.maker, LibOutcome.Outcome.OUTCOME_TWO, orderAmounts.takerAmount ); } } /// @notice Settles base tokens (not buyer and seller tokens) for the maker. /// @param order The order to settle. /// @param orderAmounts The resulting order amounts given the taker amount and parameters. function settleTransfersForMaker( LibOrder.Order memory order, LibOrderAmounts.OrderAmounts memory orderAmounts ) private { require( transferViaProxy( order.baseToken, order.maker, address(escrow), orderAmounts.takerAmount ), "CANNOT_TRANSFER_TAKER_ESCROW" ); } /// @notice Settles base tokens (not buyer and seller tokens) for the taker. /// @param order The order to settle. /// @param orderAmounts The resulting order amounts given the taker amount and parameters. /// @param taker The taker of this order. function settleTransfersForTaker( LibOrder.Order memory order, LibOrderAmounts.OrderAmounts memory orderAmounts, address taker ) private { require( transferViaProxy( order.baseToken, taker, address(escrow), orderAmounts.takerEscrow ), "CANNOT_TRANSFER_TAKER_ESCROW" ); } }
pragma solidity 0.5.16; pragma experimental ABIEncoderV2; import "../../libraries/LibOrder.sol"; import "../../interfaces/permissions/ISuperAdminRole.sol"; import "../../interfaces/trading/IFills.sol"; import "../../interfaces/trading/ICancelOrder.sol"; import "../Initializable.sol"; import "openzeppelin-solidity/contracts/math/SafeMath.sol"; /// @title CancelOrder /// @author Julian Wilson <[email protected]> /// @notice Manages functionality to cancel orders contract CancelOrder is ICancelOrder, Initializable { using LibOrder for LibOrder.Order; using SafeMath for uint256; ISuperAdminRole private superAdminRole; IFills private fills; event OrderCancel( address indexed maker, bytes32 orderHash, LibOrder.Order order ); constructor(ISuperAdminRole _superAdminRole) public Initializable() { superAdminRole = _superAdminRole; } /// @notice Throws if the caller is not a super admin. /// @param operator The caller of the method. modifier onlySuperAdmin(address operator) { require( superAdminRole.isSuperAdmin(operator), "NOT_A_SUPER_ADMIN" ); _; } /// @notice Initializes this contract with reference to other contracts /// in the protocol. /// @param _fills The Fills contract. function initialize(IFills _fills) external notInitialized onlySuperAdmin(msg.sender) { fills = _fills; initialized = true; } /// @notice Cancels an order and prevents and further filling. /// Uses the order hash to uniquely ID the order. /// @param order The order to cancel. function cancelOrder(LibOrder.Order memory order) public { assertCancelValid(order, msg.sender); fills.cancel(order); emit OrderCancel( order.maker, order.getOrderHash(), order ); } /// @notice Cancels multiple orders and prevents further filling. /// @param makerOrders The orders to cancel. function batchCancelOrders(LibOrder.Order[] memory makerOrders) public { uint256 makerOrdersLength = makerOrders.length; for (uint256 i = 0; i < makerOrdersLength; i++) { cancelOrder(makerOrders[i]); } } /// @notice Checks if a cancel is valid by the canceller. /// @param order The order to cancel. /// @param canceller The canceller that must be the maker. function assertCancelValid( LibOrder.Order memory order, address canceller ) private view { require( order.executor == address(0), "EXECUTOR_CANNOT_BE_SET" ); order.assertValidAsMaker(canceller); require( fills.remainingSpace(order) > 0, "INSUFFICIENT_SPACE" ); } }
pragma solidity 0.5.16; pragma experimental ABIEncoderV2; import "../../libraries/LibOrder.sol"; contract EIP712FillHasher { // EIP191 header for EIP712 prefix bytes2 constant private EIP191_HEADER = 0x1901; // EIP712 Domain Name value string constant private EIP712_DOMAIN_NAME = "SportX"; // EIP712 Domain Version value string constant private EIP712_DOMAIN_VERSION = "1.0"; // EIP712 typeHash of EIP712Domain bytes32 constant private EIP712_DOMAIN_SCHEMA_HASH = keccak256( abi.encodePacked( "EIP712Domain(", "string name,", "string version,", "uint256 chainId,", "address verifyingContract", ")" ) ); // EIP712 encodeType of Details bytes constant private EIP712_DETAILS_STRING = abi.encodePacked( "Details(", "string action,", "string market,", "string betting,", "string stake,", "string odds,", "string returning,", "FillObject fills", ")" ); // EIP712 encodeType of FillObject bytes constant private EIP712_FILL_OBJECT_STRING = abi.encodePacked( "FillObject(", "Order[] orders,", "bytes[] makerSigs,", "uint256[] takerAmounts,", "uint256 fillSalt", ")" ); // EIP712 encodeType of Order bytes constant private EIP712_ORDER_STRING = abi.encodePacked( "Order(", "bytes32 marketHash,", "address baseToken,", "uint256 totalBetSize,", "uint256 percentageOdds,", "uint256 expiry,", "uint256 salt,", "address maker,", "address executor,", "bool isMakerBettingOutcomeOne", ")" ); // EIP712 typeHash of Order bytes32 constant private EIP712_ORDER_HASH = keccak256( abi.encodePacked( EIP712_ORDER_STRING ) ); // EIP712 typeHash of FillObject bytes32 constant private EIP712_FILL_OBJECT_HASH = keccak256( abi.encodePacked( EIP712_FILL_OBJECT_STRING, EIP712_ORDER_STRING ) ); // EIP712 typeHash of FillObjectWithMetadata bytes32 constant private EIP712_DETAILS_HASH = keccak256( abi.encodePacked( EIP712_DETAILS_STRING, EIP712_FILL_OBJECT_STRING, EIP712_ORDER_STRING ) ); // solhint-disable var-name-mixedcase bytes32 public EIP712_DOMAIN_HASH; constructor(uint256 chainId) public { EIP712_DOMAIN_HASH = keccak256( abi.encode( EIP712_DOMAIN_SCHEMA_HASH, keccak256(bytes(EIP712_DOMAIN_NAME)), keccak256(bytes(EIP712_DOMAIN_VERSION)), chainId, address(this) ) ); } function getOrderHash(LibOrder.Order memory order) public pure returns (bytes32) { return keccak256( abi.encode( EIP712_ORDER_HASH, order.marketHash, order.baseToken, order.totalBetSize, order.percentageOdds, order.expiry, order.salt, order.maker, order.executor, order.isMakerBettingOutcomeOne ) ); } function getOrdersArrayHash(LibOrder.Order[] memory orders) public pure returns (bytes32) { bytes32[] memory ordersBytes = new bytes32[](orders.length); for (uint256 i = 0; i < orders.length; i++) { ordersBytes[i] = getOrderHash(orders[i]); } return keccak256(abi.encodePacked(ordersBytes)); } function getMakerSigsArrayHash(bytes[] memory sigs) public pure returns (bytes32) { bytes32[] memory sigsBytes = new bytes32[](sigs.length); for (uint256 i = 0; i < sigs.length; i++) { sigsBytes[i] = keccak256(sigs[i]); } return keccak256(abi.encodePacked(sigsBytes)); } function getFillObjectHash(LibOrder.FillObject memory fillObject) public pure returns (bytes32) { return keccak256( abi.encode( EIP712_FILL_OBJECT_HASH, getOrdersArrayHash(fillObject.orders), getMakerSigsArrayHash(fillObject.makerSigs), keccak256(abi.encodePacked(fillObject.takerAmounts)), fillObject.fillSalt ) ); } function getDetailsHash(LibOrder.FillDetails memory details) public view returns (bytes32) { bytes32 structHash = keccak256( abi.encode( EIP712_DETAILS_HASH, keccak256(bytes(details.action)), keccak256(bytes(details.market)), keccak256(bytes(details.betting)), keccak256(bytes(details.stake)), keccak256(bytes(details.odds)), keccak256(bytes(details.returning)), getFillObjectHash(details.fills) ) ); return keccak256( abi.encodePacked( EIP191_HEADER, EIP712_DOMAIN_HASH, structHash ) ); } function getDomainHash() public view returns (bytes32) { return EIP712_DOMAIN_HASH; } }
pragma solidity 0.5.16; pragma experimental ABIEncoderV2; import "../../interfaces/permissions/IWhitelist.sol"; import "../../interfaces/trading/IFeeSchedule.sol"; import "../../libraries/LibOrder.sol"; /// @title FeeSchedule /// @author Julian Wilson <[email protected]> /// @notice Stores the oracle fee for each token (which will presumably all be the same) contract FeeSchedule is IFeeSchedule { IWhitelist private systemParamsWhitelist; mapping(address => uint256) private oracleFees; // the convention is 10**20 = 100% event NewOracleFee( address indexed token, uint256 feeFrac ); constructor(IWhitelist _systemParamsWhitelist) public { systemParamsWhitelist = _systemParamsWhitelist; } /// @notice Throws if the caller is not a system params admin. modifier onlySystemParamsAdmin() { require( systemParamsWhitelist.getWhitelisted(msg.sender), "NOT_SYSTEM_PARAM_ADMIN" ); _; } /// @notice Throws if the fee is too high. modifier underMaxOracleFee(uint256 feeFrac) { require( feeFrac < LibOrder.getOddsPrecision(), "ORACLE_FEE_TOO_HIGH" ); _; } /// @notice Gets the oracle fee for the given token. /// @param token The token of interest. /// @return The oracle fee for this token. function getOracleFees(address token) public view returns (uint256) { return oracleFees[token]; } /// @notice Sets the oracle fee for the given token. /// @param token The token to set. /// @param feeFrac The numerator of the fee fraction function setOracleFee(address token, uint256 feeFrac) public onlySystemParamsAdmin underMaxOracleFee(feeFrac) { oracleFees[token] = feeFrac; emit NewOracleFee( token, feeFrac ); } }
pragma solidity 0.5.16; pragma experimental ABIEncoderV2; import "../../libraries/LibOrder.sol"; import "../../interfaces/trading/IFillOrder.sol"; import "../../interfaces/trading/ICancelOrder.sol"; import "../../interfaces/trading/IFills.sol"; import "openzeppelin-solidity/contracts/math/SafeMath.sol"; /// @title Fills /// @author Julian Wilson <[email protected]> /// @notice Stores the "fullness" of each order, whose ID /// is its hash. contract Fills is IFills { using LibOrder for LibOrder.Order; using SafeMath for uint256; IFillOrder private fillOrder; ICancelOrder private cancelOrder; mapping(bytes32 => uint256) private filled; mapping(bytes32 => bool) private cancelled; mapping(bytes32 => bool) private fillHashSubmitted; /// @notice Throws if the caller is not the FillOrder contract. modifier onlyFillOrder() { require( msg.sender == address(fillOrder), "ONLY_FILL_ORDER" ); _; } /// @notice Throws if the caller is not the CancelOrder contract. modifier onlyCancelOrderContract() { require( msg.sender == address(cancelOrder), "ONLY_CANCEL_ORDER_CONTRACT" ); _; } constructor(IFillOrder _fillOrder, ICancelOrder _cancelOrder) public { fillOrder = _fillOrder; cancelOrder = _cancelOrder; } /// @notice Fill an order by the given amount. /// @param order The order to fill. /// @param amount The amount to fill it by. /// @return The new filled amount for this order. function fill( LibOrder.Order memory order, uint256 amount ) public onlyFillOrder returns (uint256) { bytes32 orderHash = order.getOrderHash(); filled[orderHash] = filled[orderHash].add(amount); return filled[orderHash]; } /// @notice Cancels an order. /// @param order The order to cancel. function cancel(LibOrder.Order memory order) public onlyCancelOrderContract { bytes32 orderHash = order.getOrderHash(); cancelled[orderHash] = true; } function setFillHashSubmitted(bytes32 fillHash) public onlyFillOrder { fillHashSubmitted[fillHash] = true; } function getFilled(bytes32 orderHash) public view returns (uint256) { return filled[orderHash]; } function getCancelled(bytes32 orderHash) public view returns (bool) { return cancelled[orderHash]; } function getFillHashSubmitted(bytes32 orderHash) public view returns (bool) { return fillHashSubmitted[orderHash]; } /// @notice Check if an order has sufficient space. /// @param order The order to examine. /// @param takerAmount The amount to fill. /// @return true if there is enough space, false otherwise. function orderHasSpace( LibOrder.Order memory order, uint256 takerAmount ) public view returns (bool) { return takerAmount <= remainingSpace(order); } /// @notice Gets the remaining space for an order. /// @param order The order to check. /// @return The remaining space on the order. It returns 0 if /// the order is cancelled. function remainingSpace(LibOrder.Order memory order) public view returns (uint256) { bytes32 orderHash = order.getOrderHash(); if (cancelled[orderHash]) { return 0; } else { return order.totalBetSize.sub(filled[orderHash]); } } /// @notice Checks if the order is cancelled. /// @param order The order to check. /// @return true if the order is cancelled, false otherwise. function isOrderCancelled(LibOrder.Order memory order) public view returns(bool) { bytes32 orderHash = order.getOrderHash(); return cancelled[orderHash]; } }
pragma solidity 0.5.16; pragma experimental ABIEncoderV2; import "../../interfaces/trading/IFillOrder.sol"; import "../../interfaces/trading/ITokenTransferProxy.sol"; import "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol"; /// @title TokenTransferProxy /// @author Julian Wilson <[email protected]> /// @notice Transfers tokens on behalf of the user. contract TokenTransferProxy is ITokenTransferProxy { IFillOrder private fillOrder; constructor (IFillOrder _fillOrder) public { fillOrder = _fillOrder; } /// @notice Throws if the caller is not a fill order contract derivative modifier onlyFillOrder() { require( msg.sender == address(fillOrder), "ONLY_FILL_ORDER" ); _; } /// @notice Uses `transferFrom` and ERC20 approval to transfer tokens. /// Only callable by whitelisted addresses. /// @param token The address of the ERC20 token to transfer on the user's behalf. /// @param from The address of the user. /// @param to The destination address. /// @param value The amount to transfer. function transferFrom( address token, address from, address to, uint256 value ) public onlyFillOrder returns (bool) { return IERC20(token).transferFrom(from, to, value); } }
pragma solidity 0.5.16; contract IAffiliateRegistry { function setAffiliate(address member, address affiliate) public; function setAffiliateFeeFrac(address affiliate, uint256 fee) public; function setDefaultAffiliate(address affiliate) public; function getAffiliate(address member) public view returns (address); function getAffiliateFeeFrac(address affiliate) public view returns (uint256); function getDefaultAffiliate() public view returns (address); }
pragma solidity 0.5.16; pragma experimental ABIEncoderV2; import "../libraries/LibOutcome.sol"; contract IEscrow { struct Eligibility { bool hasEligibility; LibOutcome.Outcome outcome; uint256 amount; } function getReturnAmount(bytes32, address, address, LibOutcome.Outcome) public view returns (uint256); function getStakedAmount(bytes32, address, address, LibOutcome.Outcome) public view returns (uint256); function settleBet(address, bytes32, address) public; function updateStakedAmount(bytes32, address, address, LibOutcome.Outcome, uint256) public; function increaseReturnAmount(bytes32, address, address, LibOutcome.Outcome, uint256) public; function isMarketRedeemable(bytes32) public view returns (bool); function getEligibility(address, bytes32, address) public view returns (Eligibility memory); }
pragma solidity 0.5.16; import "../libraries/LibOutcome.sol"; contract IOutcomeReporter { function getReportedOutcome(bytes32) public view returns (LibOutcome.Outcome); function getReportTime(bytes32) public view returns (uint256); function reportOutcome(bytes32, LibOutcome.Outcome) public; function reportOutcomes(bytes32[] memory, LibOutcome.Outcome[] memory) public; }
pragma solidity 0.5.16; contract ISystemParameters { function getOracleFeeRecipient() public view returns (address); function setNewOracleFeeRecipient(address) public; }
pragma solidity 0.5.16; pragma experimental ABIEncoderV2; import "../../libraries/LibOrder.sol"; contract IOrderValidator { function getOrderStatus(LibOrder.Order memory, bytes memory) public view returns (string memory); function getMultiOrderStatus(LibOrder.Order[] memory, bytes[] memory) public view returns (string[] memory); function getFillStatus(LibOrder.FillDetails memory, bytes memory, address) public view returns (string memory); function getMetaFillStatus( LibOrder.FillDetails memory, address, bytes memory, bytes memory) public view returns (string memory); }
pragma solidity 0.5.16; contract ISuperAdminRole { function isSuperAdmin(address account) public view returns (bool); function addSuperAdmin(address account) public; function removeSuperAdmin(address account) public; function getSuperAdminCount() public view returns (uint256); }
pragma solidity 0.5.16; contract IWhitelist { function addAddressToWhitelist(address) public; function removeAddressFromWhitelist(address) public; function getWhitelisted(address) public view returns (bool); }
pragma solidity 0.5.16; contract IDetailedTokenDAI { function name() public view returns (bytes32); function symbol() public view returns (bytes32); function decimals() public view returns (uint256); }
pragma solidity 0.5.16; pragma experimental ABIEncoderV2; import "../../libraries/LibOrder.sol"; contract ICancelOrder { function cancelOrder(LibOrder.Order memory order) public; function batchCancelOrders(LibOrder.Order[] memory makerOrders) public; }
pragma solidity 0.5.16; pragma experimental ABIEncoderV2; import "../../libraries/LibOrder.sol"; contract IEIP712FillHasher { function getOrderHash(LibOrder.Order memory) public pure returns (bytes32); function getOrdersArrayHash(LibOrder.Order[] memory) public pure returns (bytes32); function getMakerSigsArrayHash(bytes[] memory) public pure returns (bytes32); function getTakerAmountsArrayHash(uint256[] memory) public pure returns (bytes32); function getFillObjectHash(LibOrder.FillObject memory) public pure returns (bytes32); function getDetailsHash(LibOrder.FillDetails memory) public view returns (bytes32); function getDomainHash() public view returns (bytes32); }
pragma solidity 0.5.16; contract IFeeSchedule { function getOracleFees(address) public view returns (uint256); function setOracleFee(address, uint256) public; }
pragma solidity 0.5.16; pragma experimental ABIEncoderV2; import "../../libraries/LibOrder.sol"; contract IFillOrder { function fillOrders(LibOrder.FillDetails memory, bytes memory) public; function metaFillOrders( LibOrder.FillDetails memory, address, bytes memory, bytes memory) public; }
pragma solidity 0.5.16; pragma experimental ABIEncoderV2; import "../../libraries/LibOrder.sol"; contract IFills { function getFilled(bytes32) public view returns (uint256); function getCancelled(bytes32) public view returns (bool); function getFillHashSubmitted(bytes32) public view returns (bool); function orderHasSpace(LibOrder.Order memory, uint256) public view returns (bool); function remainingSpace(LibOrder.Order memory) public view returns (uint256); function isOrderCancelled(LibOrder.Order memory) public view returns (bool); function fill(LibOrder.Order memory, uint256) public returns (uint256); function cancel(LibOrder.Order memory) public; function setFillHashSubmitted(bytes32) public; }
pragma solidity 0.5.16; pragma experimental ABIEncoderV2; import "../../libraries/LibOrder.sol"; contract IReadOnlyValidator { function getOrderStatus(LibOrder.Order memory, bytes memory) public view returns (string memory); function getOrderStatusForTaker( LibOrder.Order memory, address, uint256, bytes memory) public view returns (string memory); function getCumulativeOrderStatusForTaker( LibOrder.Order[] memory, address, uint256[] memory, bytes[] memory) public view returns (string memory); }
pragma solidity 0.5.16; contract ITokenTransferProxy { function transferFrom(address, address, address, uint256) public returns (bool); }
pragma solidity 0.5.16; pragma experimental ABIEncoderV2; import "openzeppelin-solidity/contracts/math/SafeMath.sol"; import "openzeppelin-solidity/contracts/cryptography/ECDSA.sol"; /// @title LibOrder /// @author Julian Wilson <[email protected]> /// @notice Central definition for what an "order" is along with utilities for an order. library LibOrder { using SafeMath for uint256; uint256 public constant ODDS_PRECISION = 10**20; struct Order { bytes32 marketHash; address baseToken; uint256 totalBetSize; uint256 percentageOdds; uint256 expiry; uint256 salt; address maker; address executor; bool isMakerBettingOutcomeOne; } struct FillObject { Order[] orders; bytes[] makerSigs; uint256[] takerAmounts; uint256 fillSalt; } struct FillDetails { string action; string market; string betting; string stake; string odds; string returning; FillObject fills; } /// @notice Checks the parameters of the given order to see if it conforms to the protocol. /// @param order The order to check. /// @return A status string in UPPER_SNAKE_CASE. It will return "OK" if everything checks out. // solhint-disable code-complexity function getParamValidity(Order memory order) internal view returns (string memory) { if (order.totalBetSize == 0) {return "TOTAL_BET_SIZE_ZERO";} if (order.percentageOdds == 0 || order.percentageOdds >= ODDS_PRECISION) {return "INVALID_PERCENTAGE_ODDS";} if (order.expiry < now) {return "ORDER_EXPIRED";} if (order.baseToken == address(0)) {return "BASE_TOKEN";} return "OK"; } /// @notice Checks the signature of an order to see if /// it was an order signed by the given maker. /// @param order The order to check. /// @param makerSig The signature to compare. /// @return true if the signature matches, false otherwise. function checkSignature(Order memory order, bytes memory makerSig) internal pure returns (bool) { bytes32 orderHash = getOrderHash(order); return ECDSA.recover(ECDSA.toEthSignedMessageHash(orderHash), makerSig) == order.maker; } /// @notice Checks if an order's parameters conforms to the protocol's specifications. /// @param order The order to check. function assertValidParams(Order memory order) internal view { require( order.totalBetSize > 0, "TOTAL_BET_SIZE_ZERO" ); require( order.percentageOdds > 0 && order.percentageOdds < ODDS_PRECISION, "INVALID_PERCENTAGE_ODDS" ); require(order.baseToken != address(0), "INVALID_BASE_TOKEN"); require(order.expiry > now, "ORDER_EXPIRED"); } /// @notice Checks if an order has valid parameters including /// the signature and checks if the maker is not the taker. /// @param order The order to check. /// @param taker The hypothetical filler of this order, i.e., the taker. /// @param makerSig The signature to check. function assertValidAsTaker(Order memory order, address taker, bytes memory makerSig) internal view { assertValidParams(order); require( checkSignature(order, makerSig), "SIGNATURE_MISMATCH" ); require(order.maker != taker, "TAKER_NOT_MAKER"); } /// @notice Checks if the order has valid parameters /// and checks if the sender is the maker. /// @param order The order to check. /// @param sender The address to compare the maker to. function assertValidAsMaker(Order memory order, address sender) internal view { assertValidParams(order); require(order.maker == sender, "CALLER_NOT_MAKER"); } /// @notice Computes the hash of an order. Packs the arguments in order /// of the Order struct. /// @param order The order to compute the hash of. function getOrderHash(Order memory order) internal pure returns (bytes32) { return keccak256( abi.encodePacked( order.marketHash, order.baseToken, order.totalBetSize, order.percentageOdds, order.expiry, order.salt, order.maker, order.executor, order.isMakerBettingOutcomeOne ) ); } function getOddsPrecision() internal pure returns (uint256) { return ODDS_PRECISION; } }
pragma solidity 0.5.16; pragma experimental ABIEncoderV2; import "./LibOrder.sol"; import "openzeppelin-solidity/contracts/math/SafeMath.sol"; /// @title LibOrderAmounts /// @author Julian Wilson <[email protected]> /// @notice Struct definition for the resulting individual computed amounts /// when filling an order. library LibOrderAmounts { using SafeMath for uint256; struct OrderAmounts { uint256 takerAmount; uint256 takerEscrow; uint256 potSize; } /// @notice Computes the tokens that should be transferred as a result of /// the order and the specified fill amount. /// @param order The reference maker order /// @param takerAmount The amount to fill of this order. /// @return An OrderAmounts struct. function computeOrderAmounts( LibOrder.Order memory order, uint256 takerAmount ) internal pure returns (LibOrderAmounts.OrderAmounts memory) { uint256 oddsPrecision = LibOrder.getOddsPrecision(); uint256 potSize = takerAmount.mul(oddsPrecision).div(order.percentageOdds); uint256 takerEscrow = potSize.sub(takerAmount); return LibOrderAmounts.OrderAmounts({ takerAmount: takerAmount, takerEscrow: takerEscrow, potSize: potSize }); } /// @notice Combines two OrderAmounts into one by adding up /// the values /// @param orderAmount1 The first OrderAmount /// @param orderAmount2 The second OrderAmount /// @return The combined OrderAmounts struct. function reduceOrderAmounts( LibOrderAmounts.OrderAmounts memory orderAmount1, LibOrderAmounts.OrderAmounts memory orderAmount2 ) internal pure returns (LibOrderAmounts.OrderAmounts memory) { return LibOrderAmounts.OrderAmounts({ takerAmount: orderAmount1.takerAmount.add(orderAmount2.takerAmount), takerEscrow: orderAmount1.takerEscrow.add(orderAmount2.takerEscrow), potSize: orderAmount1.potSize.add(orderAmount2.potSize) }); } /// @notice Takes a bunch of orders and taker amounts /// and computes the total order amounts /// @param makerOrders The reference maker orders /// @param takerAmounts An array of taker amounts, one for each order /// @return The total OrderAmounts struct. function computeTotalOrderAmounts( LibOrder.Order[] memory makerOrders, uint256[] memory takerAmounts ) internal pure returns (LibOrderAmounts.OrderAmounts memory) { LibOrderAmounts.OrderAmounts memory combinedOrderAmounts; uint256 makerOrdersLength = makerOrders.length; for (uint256 i = 0; i < makerOrdersLength; i++) { LibOrderAmounts.OrderAmounts memory orderAmounts = computeOrderAmounts( makerOrders[i], takerAmounts[i] ); combinedOrderAmounts = reduceOrderAmounts(combinedOrderAmounts, orderAmounts); } return combinedOrderAmounts; } }
pragma solidity 0.5.16; pragma experimental ABIEncoderV2; /// @title LibOutcome /// @author Julian Wilson <[email protected]> /// @notice Enumerations and utilities related to voting. library LibOutcome { enum Outcome { VOID, OUTCOME_ONE, OUTCOME_TWO } }
pragma solidity 0.5.16; pragma experimental ABIEncoderV2; /// @title LibString /// @author Julian Wilson <[email protected]> /// @notice Utility to efficiently compare strings when necessary. library LibString { /// @notice Compares two strings by taking their hash. /// @param a The first string. /// @param b The second string. /// @return true or false depending on if the strings matched. function equals(string memory a, string memory b) internal pure returns (bool) { return keccak256(abi.encodePacked(a)) == keccak256(abi.encodePacked(b)); } }
pragma solidity ^0.5.0; /** * @title SafeMath * @dev Unsigned math operations with safety checks that revert on error */ library SafeMath { /** * @dev Multiplies two unsigned integers, 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 unsigned integers truncating the quotient, reverts on division by zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 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 unsigned integers, 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 unsigned integers, 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 unsigned integers 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; } }
pragma solidity ^0.5.0; /** * @title ERC20 interface * @dev see https://github.com/ethereum/EIPs/issues/20 */ interface IERC20 { 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); function totalSupply() external view returns (uint256); function balanceOf(address who) external view returns (uint256); function allowance(address owner, address spender) external view returns (uint256); event Transfer(address indexed from, address indexed to, uint256 value); event Approval(address indexed owner, address indexed spender, uint256 value); }
pragma solidity ^0.5.0; /** * @title Roles * @dev Library for managing addresses assigned to a Role. */ library Roles { struct Role { mapping (address => bool) bearer; } /** * @dev give an account access to this role */ function add(Role storage role, address account) internal { require(account != address(0)); require(!has(role, account)); role.bearer[account] = true; } /** * @dev remove an account's access to this role */ function remove(Role storage role, address account) internal { require(account != address(0)); require(has(role, account)); role.bearer[account] = false; } /** * @dev check if an account has this role * @return bool */ function has(Role storage role, address account) internal view returns (bool) { require(account != address(0)); return role.bearer[account]; } }
pragma solidity ^0.5.0; /** * @title Elliptic curve signature operations * @dev Based on https://gist.github.com/axic/5b33912c6f61ae6fd96d6c4a47afde6d * TODO Remove this library once solidity supports passing a signature to ecrecover. * See https://github.com/ethereum/solidity/issues/864 */ library ECDSA { /** * @dev Recover signer address from a message by using their signature * @param hash bytes32 message, the hash is the signed message. What is recovered is the signer address. * @param signature bytes signature, the signature is generated using web3.eth.sign() */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { bytes32 r; bytes32 s; uint8 v; // Check the signature length if (signature.length != 65) { return (address(0)); } // Divide the signature in r, s and v variables // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. // solhint-disable-next-line no-inline-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } // Version of signature should be 27 or 28, but 0 and 1 are also possible versions if (v < 27) { v += 27; } // If the version is correct return the signer address if (v != 27 && v != 28) { return (address(0)); } else { return ecrecover(hash, v, r, s); } } /** * toEthSignedMessageHash * @dev prefix a bytes32 value with "\x19Ethereum Signed Message:" * and hash the result */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) { // 32 is the length in bytes of hash, // enforced by the type signature above return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); } }
{ "optimizer": { "enabled": true, "runs": 200, "details": { "yul": true } }, "remappings": [], "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract ISuperAdminRole","name":"_superAdminRole","type":"address"},{"internalType":"contract IEIP712FillHasher","name":"_eip712FillHasher","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"maker","type":"address"},{"indexed":true,"internalType":"bytes32","name":"marketHash","type":"bytes32"},{"indexed":true,"internalType":"address","name":"taker","type":"address"},{"indexed":false,"internalType":"uint256","name":"newFilledAmount","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"orderHash","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"fillHash","type":"bytes32"},{"components":[{"internalType":"bytes32","name":"marketHash","type":"bytes32"},{"internalType":"address","name":"baseToken","type":"address"},{"internalType":"uint256","name":"totalBetSize","type":"uint256"},{"internalType":"uint256","name":"percentageOdds","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"address","name":"maker","type":"address"},{"internalType":"address","name":"executor","type":"address"},{"internalType":"bool","name":"isMakerBettingOutcomeOne","type":"bool"}],"indexed":false,"internalType":"struct LibOrder.Order","name":"order","type":"tuple"},{"components":[{"internalType":"uint256","name":"takerAmount","type":"uint256"},{"internalType":"uint256","name":"takerEscrow","type":"uint256"},{"internalType":"uint256","name":"potSize","type":"uint256"}],"indexed":false,"internalType":"struct LibOrderAmounts.OrderAmounts","name":"orderAmounts","type":"tuple"}],"name":"OrderFill","type":"event"},{"constant":false,"inputs":[{"components":[{"internalType":"string","name":"action","type":"string"},{"internalType":"string","name":"market","type":"string"},{"internalType":"string","name":"betting","type":"string"},{"internalType":"string","name":"stake","type":"string"},{"internalType":"string","name":"odds","type":"string"},{"internalType":"string","name":"returning","type":"string"},{"components":[{"components":[{"internalType":"bytes32","name":"marketHash","type":"bytes32"},{"internalType":"address","name":"baseToken","type":"address"},{"internalType":"uint256","name":"totalBetSize","type":"uint256"},{"internalType":"uint256","name":"percentageOdds","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"address","name":"maker","type":"address"},{"internalType":"address","name":"executor","type":"address"},{"internalType":"bool","name":"isMakerBettingOutcomeOne","type":"bool"}],"internalType":"struct LibOrder.Order[]","name":"orders","type":"tuple[]"},{"internalType":"bytes[]","name":"makerSigs","type":"bytes[]"},{"internalType":"uint256[]","name":"takerAmounts","type":"uint256[]"},{"internalType":"uint256","name":"fillSalt","type":"uint256"}],"internalType":"struct LibOrder.FillObject","name":"fills","type":"tuple"}],"internalType":"struct LibOrder.FillDetails","name":"fillDetails","type":"tuple"},{"internalType":"bytes","name":"executorSig","type":"bytes"}],"name":"fillOrders","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"contract IFills","name":"_fills","type":"address"},{"internalType":"contract IEscrow","name":"_escrow","type":"address"},{"internalType":"contract ITokenTransferProxy","name":"_tokenTransferProxy","type":"address"},{"internalType":"contract IOutcomeReporter","name":"_outcomeReporter","type":"address"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"initialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"components":[{"internalType":"string","name":"action","type":"string"},{"internalType":"string","name":"market","type":"string"},{"internalType":"string","name":"betting","type":"string"},{"internalType":"string","name":"stake","type":"string"},{"internalType":"string","name":"odds","type":"string"},{"internalType":"string","name":"returning","type":"string"},{"components":[{"components":[{"internalType":"bytes32","name":"marketHash","type":"bytes32"},{"internalType":"address","name":"baseToken","type":"address"},{"internalType":"uint256","name":"totalBetSize","type":"uint256"},{"internalType":"uint256","name":"percentageOdds","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"address","name":"maker","type":"address"},{"internalType":"address","name":"executor","type":"address"},{"internalType":"bool","name":"isMakerBettingOutcomeOne","type":"bool"}],"internalType":"struct LibOrder.Order[]","name":"orders","type":"tuple[]"},{"internalType":"bytes[]","name":"makerSigs","type":"bytes[]"},{"internalType":"uint256[]","name":"takerAmounts","type":"uint256[]"},{"internalType":"uint256","name":"fillSalt","type":"uint256"}],"internalType":"struct LibOrder.FillObject","name":"fills","type":"tuple"}],"internalType":"struct LibOrder.FillDetails","name":"fillDetails","type":"tuple"},{"internalType":"address","name":"taker","type":"address"},{"internalType":"bytes","name":"takerSig","type":"bytes"},{"internalType":"bytes","name":"executorSig","type":"bytes"}],"name":"metaFillOrders","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b50604051620026bf380380620026bf833981016040819052620000349162000066565b600380546001600160a01b039384166001600160a01b03199182161790915560058054929093169116179055620000bd565b6000806040838503121562000079578182fd5b82516200008681620000a4565b60208401519092506200009981620000a4565b809150509250929050565b6001600160a01b0381168114620000ba57600080fd5b50565b6125f280620000cd6000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c8063158ef93e14610051578063220bfc541461006f5780639a89f58914610084578063f8c8765e14610097575b600080fd5b6100596100aa565b6040516100669190612045565b60405180910390f35b61008261007d366004611d32565b6100b3565b005b610082610092366004611c99565b610393565b6100826100a5366004611c3e565b6106d2565b60005460ff1681565b60008260c00151600001516000815181106100ca57fe5b602002602001015160e00151905060008360c0015160400151518460c001516000015151148015610106575060c0840151602081015151905151145b61012b5760405162461bcd60e51b81526004016101229061219d565b60405180910390fd5b6001600160a01b0382161561036f576005546040516334640aad60e21b81526001600160a01b039091169063d1902ab49061016a90879060040161241a565b60206040518083038186803b15801561018257600080fd5b505afa158015610196573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506101ba9190810190611c26565b600154604051631a5ab2cb60e31b81529192506001600160a01b03169063d2d59658906101eb908490600401612050565b60206040518083038186803b15801561020357600080fd5b505afa158015610217573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061023b9190810190611c0a565b156102585760405162461bcd60e51b815260040161012290612236565b816001600160a01b031661026c82856107f8565b6001600160a01b0316146102925760405162461bcd60e51b8152600401610122906123ac565b60c084015151516001101561030c5760015b60c0850151515181101561030a57826001600160a01b03168560c001516000015182815181106102d057fe5b602002602001015160e001516001600160a01b0316146103025760405162461bcd60e51b815260040161012290612353565b6001016102a4565b505b6001546040516339d63abd60e21b81526001600160a01b039091169063e758eaf49061033c908490600401612050565b600060405180830381600087803b15801561035657600080fd5b505af115801561036a573d6000803e3d6000fd5b505050505b60c08401518051604082015160209092015161038d929033856108b9565b50505050565b6005546040516334640aad60e21b81526000916001600160a01b03169063d1902ab4906103c490889060040161241a565b60206040518083038186803b1580156103dc57600080fd5b505afa1580156103f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506104149190810190611c26565b9050836001600160a01b031661042a82856107f8565b6001600160a01b0316146104505760405162461bcd60e51b81526004016101229061229d565b600154604051631a5ab2cb60e31b81526001600160a01b039091169063d2d5965890610480908490600401612050565b60206040518083038186803b15801561049857600080fd5b505afa1580156104ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506104d09190810190611c0a565b156104ed5760405162461bcd60e51b815260040161012290612236565b60008560c001516000015160008151811061050457fe5b602002602001015160e00151905060006001600160a01b0316816001600160a01b03161461058e57336001600160a01b038216146105545760405162461bcd60e51b815260040161012290612266565b806001600160a01b031661056883856107f8565b6001600160a01b03161461058e5760405162461bcd60e51b8152600401610122906123ac565b60c08601516040810151519051511480156105b4575060c0860151602081015151905151145b6105d05760405162461bcd60e51b81526004016101229061219d565b60c086015151516001101561064a5760015b60c0870151515181101561064857816001600160a01b03168760c0015160000151828151811061060e57fe5b602002602001015160e001516001600160a01b0316146106405760405162461bcd60e51b815260040161012290612353565b6001016105e2565b505b60c086015180516040820151602090920151610668929088866108b9565b6001546040516339d63abd60e21b81526001600160a01b039091169063e758eaf490610698908590600401612050565b600060405180830381600087803b1580156106b257600080fd5b505af11580156106c6573d6000803e3d6000fd5b50505050505050505050565b60005460ff16156106f55760405162461bcd60e51b815260040161012290612144565b60035460405163df7f453b60e01b815233916001600160a01b03169063df7f453b90610725908490600401612007565b60206040518083038186803b15801561073d57600080fd5b505afa158015610751573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506107759190810190611c0a565b6107915760405162461bcd60e51b81526004016101229061220b565b50600180546001600160a01b039586166001600160a01b031991821617825560028054958716958216959095179094556000805460048054948816949096169390931790945560ff199290941661010002610100600160a81b031990911617169091179055565b600080600080845160411461081357600093505050506108b3565b50505060208201516040830151606084015160001a601b81101561083557601b015b8060ff16601b1415801561084d57508060ff16601c14155b1561085e57600093505050506108b3565b600186828585604051600081526020016040526040516108819493929190612094565b6020604051602081039080840390855afa1580156108a3573d6000803e3d6000fd5b5050506020604051035193505050505b92915050565b60006108c786868686610930565b905080156108e0576108db86868585610a9e565b610928565b60005b86518110156109265761091e8782815181106108fb57fe5b602002602001015187838151811061090f57fe5b60200260200101518686610ae4565b6001016108e3565b505b505050505050565b6000808560008151811061094057fe5b60200260200101516101000151905060008660008151811061095e57fe5b602002602001015160000151905060008760008151811061097b57fe5b602002602001015160200151905060008090505b88518110156109e5576109dd8982815181106109a757fe5b60200260200101518983815181106109bb57fe5b6020026020010151888a85815181106109d057fe5b6020026020010151610b04565b60010161098f565b50600188511115610a8e5760015b8851811015610a8c57831515898281518110610a0b57fe5b602002602001015161010001511515141580610a3e575082898281518110610a2f57fe5b60200260200101516000015114155b80610a725750816001600160a01b0316898281518110610a5a57fe5b6020026020010151602001516001600160a01b031614155b15610a84576000945050505050610a96565b6001016109f3565b505b600193505050505b949350505050565b610aa66117d9565b610ab08585610c70565b9050610ad185600081518110610ac257fe5b60200260200101518285610ce6565b610add85858585610d01565b5050505050565b610aec6117d9565b610af68585610eb6565b9050610add85828585610f2b565b60008311610b245760405162461bcd60e51b81526004016101229061210d565b610b3584838363ffffffff61103216565b600480548551604051637d4b2a1960e01b81526001600160a01b0390921692637d4b2a1992610b65929101612050565b60206040518083038186803b158015610b7d57600080fd5b505afa158015610b91573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610bb59190810190611c26565b15610bd25760405162461bcd60e51b8152600401610122906120b2565b60015460405163a5f650d760e01b81526001600160a01b039091169063a5f650d790610c0490879087906004016124ed565b60206040518083038186803b158015610c1c57600080fd5b505afa158015610c30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610c549190810190611c0a565b61038d5760405162461bcd60e51b815260040161012290612327565b610c786117d9565b610c806117d9565b835160005b81811015610cdc57610c956117d9565b610cc5878381518110610ca457fe5b6020026020010151878481518110610cb857fe5b6020026020010151610eb6565b9050610cd18482611097565b935050600101610c85565b5090949350505050565b610cf1838383611109565b610cfc8383836112e3565b505050565b60005b8451811015610add57610d156117d9565b610d38868381518110610d2457fe5b6020026020010151868481518110610cb857fe5b60015487519192506000916001600160a01b039091169063c9f67f9c90899086908110610d6157fe5b602002602001015184600001516040518363ffffffff1660e01b8152600401610d8b9291906124ed565b602060405180830381600087803b158015610da557600080fd5b505af1158015610db9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610ddd9190810190611c26565b9050610dfc878481518110610dee57fe5b602002602001015183611323565b846001600160a01b0316878481518110610e1257fe5b602002602001015160000151888581518110610e2a57fe5b602002602001015160c001516001600160a01b03167f7fce7b83d2014c90bf64f0281296c1ecf7429a9473167b683f3f14c55bfe9e1f84610e7d8c8981518110610e7057fe5b602002602001015161133b565b898d8a81518110610e8a57fe5b602002602001015189604051610ea495949392919061250a565b60405180910390a45050600101610d04565b610ebe6117d9565b6000610ec8611398565b90506000610ef38560600151610ee784876113a590919063ffffffff16565b9063ffffffff6113d316565b90506000610f07828663ffffffff6113f516565b60408051606081018252968752602087019190915285019190915250919392505050565b600154835160405163327d9fe760e21b81526000926001600160a01b03169163c9f67f9c91610f5e9189916004016124ed565b602060405180830381600087803b158015610f7857600080fd5b505af1158015610f8c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610fb09190810190611c26565b9050610fbc8585611323565b610fc7858585610ce6565b826001600160a01b031685600001518660c001516001600160a01b03167f7fce7b83d2014c90bf64f0281296c1ecf7429a9473167b683f3f14c55bfe9e1f8461100f8a61133b565b878b8b60405161102395949392919061250a565b60405180910390a45050505050565b61103b8361140a565b61104583826114ba565b6110615760405162461bcd60e51b815260040161012290612171565b816001600160a01b03168360c001516001600160a01b03161415610cfc5760405162461bcd60e51b815260040161012290612383565b61109f6117d9565b60408051606081019091528251845182916110c0919063ffffffff6114fa16565b81526020016110e0846020015186602001516114fa90919063ffffffff16565b8152602001611100846040015186604001516114fa90919063ffffffff16565b90529392505050565b82610100015115611201576002805484516020860151604080870151905163c6b4931560e01b81526001600160a01b039094169463c6b4931594611154949392889291600401612059565b600060405180830381600087803b15801561116e57600080fd5b505af1158015611182573d6000803e3d6000fd5b50506002805486516020808901519088015160405163904e531b60e01b81526001600160a01b03909416965063904e531b95506111ca94929391928892909190600401612059565b600060405180830381600087803b1580156111e457600080fd5b505af11580156111f8573d6000803e3d6000fd5b50505050610cfc565b60025483516020850151604080860151905163c6b4931560e01b81526001600160a01b039094169363c6b493159361124493909290918791600191600401612059565b600060405180830381600087803b15801561125e57600080fd5b505af1158015611272573d6000803e3d6000fd5b505060025485516020808801519087015160405163904e531b60e01b81526001600160a01b03909416955063904e531b94506112b5938791600191600401612059565b600060405180830381600087803b1580156112cf57600080fd5b505af1158015610926573d6000803e3d6000fd5b602080840151600254918401516113079284916001600160a01b039091169061150c565b610cfc5760405162461bcd60e51b8152600401610122906123e3565b61132d82826115a2565b6113378282611786565b5050565b80516020808301516040808501516060860151608087015160a088015160c089015160e08a01516101008b0151965160009a61137b9a9099989101611f77565b604051602081830303815290604052805190602001209050919050565b68056bc75e2d6310000090565b6000826113b4575060006108b3565b828202828482816113c157fe5b04146113cc57600080fd5b9392505050565b60008082116113e157600080fd5b60008284816113ec57fe5b04949350505050565b60008282111561140457600080fd5b50900390565b600081604001511161142e5760405162461bcd60e51b8152600401610122906120e0565b6000816060015111801561144e575068056bc75e2d631000008160600151105b61146a5760405162461bcd60e51b8152600401610122906121d4565b60208101516001600160a01b03166114945760405162461bcd60e51b8152600401610122906122fb565b428160800151116114b75760405162461bcd60e51b8152600401610122906122d4565b50565b6000806114c68461133b565b90508360c001516001600160a01b03166114e86114e2836117c6565b856107f8565b6001600160a01b031614949350505050565b6000828201838110156113cc57600080fd5b60008054604051630aed65f560e11b81526101009091046001600160a01b0316906315dacbea9061154790889088908890889060040161201b565b602060405180830381600087803b15801561156157600080fd5b505af1158015611575573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506115999190810190611c0a565b95945050505050565b8161010001511561169f576002548251602084015160c0850151604080860151905163c6b4931560e01b81526001600160a01b039095169463c6b49315946115f69490939092909160019190600401612059565b600060405180830381600087803b15801561161057600080fd5b505af1158015611624573d6000803e3d6000fd5b50506002548451602086015160c0870151865160405163904e531b60e01b81526001600160a01b03909516965063904e531b95506116689460019190600401612059565b600060405180830381600087803b15801561168257600080fd5b505af1158015611696573d6000803e3d6000fd5b50505050611337565b600280548351602085015160c0860151604080870151905163c6b4931560e01b81526001600160a01b039095169563c6b49315956116e39594939290600401612059565b600060405180830381600087803b1580156116fd57600080fd5b505af1158015611711573d6000803e3d6000fd5b5050600280548551602087015160c0880151875160405163904e531b60e01b81526001600160a01b03909516975063904e531b965061175895939492939192600401612059565b600060405180830381600087803b15801561177257600080fd5b505af1158015610928573d6000803e3d6000fd5b602082015160c083015160025483516117aa9392916001600160a01b03169061150c565b6113375760405162461bcd60e51b8152600401610122906123e3565b60008160405160200161137b9190611fd6565b60405180606001604052806000815260200160008152602001600081525090565b80356108b38161258c565b600082601f830112611815578081fd5b81356118286118238261256c565b612545565b8181529150602080830190840160005b838110156118655761185087602084358901016119d9565b83526020928301929190910190600101611838565b5050505092915050565b600082601f83011261187f578081fd5b813561188d6118238261256c565b8181529150602080830190848101610120808502870183018810156118b157600080fd5b60005b858110156119595781838a0312156118cb57600080fd5b6118d482612545565b833581526118e48a8686016117fa565b8582015260408401356040820152606084013560608201526080840135608082015260a084013560a082015261191d8a60c086016117fa565b60c082015261192f8a60e086016117fa565b60e08201526101006119438b8287016119ce565b90820152855293830193918101916001016118b4565b50505050505092915050565b600082601f830112611975578081fd5b81356119836118238261256c565b8181529150602080830190848101818402860182018710156119a457600080fd5b60005b848110156119c3578135845292820192908201906001016119a7565b505050505092915050565b80356108b3816125a1565b600082601f8301126119e9578081fd5b813567ffffffffffffffff8111156119ff578182fd5b611a12601f8201601f1916602001612545565b9150808252836020828501011115611a2957600080fd5b8060208401602084013760009082016020015292915050565b600060e08284031215611a53578081fd5b611a5d60e0612545565b9050813567ffffffffffffffff80821115611a7757600080fd5b611a83858386016119d9565b83526020840135915080821115611a9957600080fd5b611aa5858386016119d9565b60208401526040840135915080821115611abe57600080fd5b611aca858386016119d9565b60408401526060840135915080821115611ae357600080fd5b611aef858386016119d9565b60608401526080840135915080821115611b0857600080fd5b611b14858386016119d9565b608084015260a0840135915080821115611b2d57600080fd5b611b39858386016119d9565b60a084015260c0840135915080821115611b5257600080fd5b50611b5f84828501611b6b565b60c08301525092915050565b600060808284031215611b7c578081fd5b611b866080612545565b9050813567ffffffffffffffff80821115611ba057600080fd5b611bac8583860161186f565b83526020840135915080821115611bc257600080fd5b611bce85838601611805565b60208401526040840135915080821115611be757600080fd5b50611bf484828501611965565b6040830152506060820135606082015292915050565b600060208284031215611c1b578081fd5b81516113cc816125a1565b600060208284031215611c37578081fd5b5051919050565b60008060008060808587031215611c53578283fd5b8435611c5e8161258c565b93506020850135611c6e8161258c565b92506040850135611c7e8161258c565b91506060850135611c8e8161258c565b939692955090935050565b60008060008060808587031215611cae578182fd5b843567ffffffffffffffff80821115611cc5578384fd5b611cd188838901611a42565b955060208701359150611ce38261258c565b90935060408601359080821115611cf8578384fd5b611d04888389016119d9565b93506060870135915080821115611d19578283fd5b50611d26878288016119d9565b91505092959194509250565b60008060408385031215611d44578182fd5b823567ffffffffffffffff80821115611d5b578384fd5b611d6786838701611a42565b93506020850135915080821115611d7c578283fd5b50611d89858286016119d9565b9150509250929050565b6000815180845260208401935060208301825b82811015611dc4578151865260209586019590910190600101611da6565b5093949350505050565b15159052565b60008151808452815b81811015611df957602081850181015186830182015201611ddd565b81811115611e0a5782602083870101525b50601f01601f19169290920160200192915050565b805160808084528151908401819052600091602091839160a08701919084015b81841015611e6857611e52838251611f0a565b6001939093019261012092909201918401611e3f565b50508483015186820387850152805180835285935082850191818602840186019086015b82861015611ebc57601f19858303018452611ea8828251611dd4565b600196909601959387019391508601611e8c565b506040880151955088810360408a0152611ed68187611d93565b94505050505060608401516060860152809250505092915050565b8051825260208082015190830152604090810151910152565b80518252602081015160018060a01b03808216602085015260408301516040850152606083015160608501526080830151608085015260a083015160a08501528060c08401511660c08501528060e08401511660e085015250506101008082015161038d82850182611dce565b9889526bffffffffffffffffffffffff19606098891b811660208b015260348a0197909752605489019590955260748801939093526094870191909152841b831660b486015290921b1660c8830152151560f81b60dc82015260dd0190565b7f19457468657265756d205369676e6564204d6573736167653a0a3332000000008152601c810191909152603c0190565b6001600160a01b0391909116815260200190565b6001600160a01b039485168152928416602084015292166040820152606081019190915260800190565b901515815260200190565b90815260200190565b8581526001600160a01b0385811660208301528416604082015260a081016003841061208157fe5b6060820193909352608001529392505050565b93845260ff9290921660208401526040830152606082015260800190565b6020808252601490820152734d41524b45545f4e4f545f545241444541424c4560601b604082015260600190565b602080825260139082015272544f54414c5f4245545f53495a455f5a45524f60681b604082015260600190565b60208082526019908201527f54414b45525f414d4f554e545f4e4f545f504f53495449564500000000000000604082015260600190565b6020808252601390820152721053149150511657d253925512505312569151606a1b604082015260600190565b6020808252601290820152710a6928e9c82a8aaa48abe9a92a69a82a886960731b604082015260600190565b60208082526017908201527f494e434f52524543545f41525241595f4c454e47544853000000000000000000604082015260600190565b60208082526017908201527f494e56414c49445f50455243454e544147455f4f444453000000000000000000604082015260600190565b6020808252601190820152702727aa2fa0afa9aaa822a92fa0a226a4a760791b604082015260600190565b6020808252601690820152751192531317d053149150511657d4d55093525515115160521b604082015260600190565b60208082526017908201527f53454e4445525f4d5553545f42455f4558454355544f52000000000000000000604082015260600190565b60208082526018908201527f54414b45525f5349474e41545552455f4d49534d415443480000000000000000604082015260600190565b6020808252600d908201526c13d491115497d1561412549151609a1b604082015260600190565b60208082526012908201527124a72b20a624a22fa120a9a2afaa27a5a2a760711b604082015260600190565b602080825260129082015271494e53554646494349454e545f535041434560701b604082015260600190565b602080825260169082015275494e434f4e53495354454e545f4558454355544f525360501b604082015260600190565b6020808252600f908201526e2a20a5a2a92fa727aa2fa6a0a5a2a960891b604082015260600190565b6020808252601b908201527f4558454355544f525f5349474e41545552455f4d49534d415443480000000000604082015260600190565b6020808252601c908201527f43414e4e4f545f5452414e534645525f54414b45525f455343524f5700000000604082015260600190565b600060208252825160e06020840152612437610100840182611dd4565b60208501519150601f19808583030160408601526124558284611dd4565b60408701519350818682030160608701526124708185611dd4565b925050606086015192508085830301608086015261248e8284611dd4565b60808701519350818682030160a08701526124a98185611dd4565b92505060a08601519250808583030160c08601526124c78284611dd4565b60c08701519350818682030160e08701526124e28185611e1f565b979650505050505050565b61014081016124fc8285611f0a565b826101208301529392505050565b85815260208101859052604081018490526101e0810161252d6060830185611f0a565b61253b610180830184611ef1565b9695505050505050565b60405181810167ffffffffffffffff8111828210171561256457600080fd5b604052919050565b600067ffffffffffffffff821115612582578081fd5b5060209081020190565b6001600160a01b03811681146114b757600080fd5b80151581146114b757600080fdfea365627a7a72315820af59bc471fef2ae8427d4dcfc1cce3d5f11d7b83e8d4a51016d4186688de536f6c6578706572696d656e74616cf564736f6c6343000510004000000000000000000000000087d712688a706d4343704eeb382cb72abe76452e00000000000000000000000090c997f83885b4bd16d3ef8add73b9d901d49095
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061004c5760003560e01c8063158ef93e14610051578063220bfc541461006f5780639a89f58914610084578063f8c8765e14610097575b600080fd5b6100596100aa565b6040516100669190612045565b60405180910390f35b61008261007d366004611d32565b6100b3565b005b610082610092366004611c99565b610393565b6100826100a5366004611c3e565b6106d2565b60005460ff1681565b60008260c00151600001516000815181106100ca57fe5b602002602001015160e00151905060008360c0015160400151518460c001516000015151148015610106575060c0840151602081015151905151145b61012b5760405162461bcd60e51b81526004016101229061219d565b60405180910390fd5b6001600160a01b0382161561036f576005546040516334640aad60e21b81526001600160a01b039091169063d1902ab49061016a90879060040161241a565b60206040518083038186803b15801561018257600080fd5b505afa158015610196573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506101ba9190810190611c26565b600154604051631a5ab2cb60e31b81529192506001600160a01b03169063d2d59658906101eb908490600401612050565b60206040518083038186803b15801561020357600080fd5b505afa158015610217573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061023b9190810190611c0a565b156102585760405162461bcd60e51b815260040161012290612236565b816001600160a01b031661026c82856107f8565b6001600160a01b0316146102925760405162461bcd60e51b8152600401610122906123ac565b60c084015151516001101561030c5760015b60c0850151515181101561030a57826001600160a01b03168560c001516000015182815181106102d057fe5b602002602001015160e001516001600160a01b0316146103025760405162461bcd60e51b815260040161012290612353565b6001016102a4565b505b6001546040516339d63abd60e21b81526001600160a01b039091169063e758eaf49061033c908490600401612050565b600060405180830381600087803b15801561035657600080fd5b505af115801561036a573d6000803e3d6000fd5b505050505b60c08401518051604082015160209092015161038d929033856108b9565b50505050565b6005546040516334640aad60e21b81526000916001600160a01b03169063d1902ab4906103c490889060040161241a565b60206040518083038186803b1580156103dc57600080fd5b505afa1580156103f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506104149190810190611c26565b9050836001600160a01b031661042a82856107f8565b6001600160a01b0316146104505760405162461bcd60e51b81526004016101229061229d565b600154604051631a5ab2cb60e31b81526001600160a01b039091169063d2d5965890610480908490600401612050565b60206040518083038186803b15801561049857600080fd5b505afa1580156104ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506104d09190810190611c0a565b156104ed5760405162461bcd60e51b815260040161012290612236565b60008560c001516000015160008151811061050457fe5b602002602001015160e00151905060006001600160a01b0316816001600160a01b03161461058e57336001600160a01b038216146105545760405162461bcd60e51b815260040161012290612266565b806001600160a01b031661056883856107f8565b6001600160a01b03161461058e5760405162461bcd60e51b8152600401610122906123ac565b60c08601516040810151519051511480156105b4575060c0860151602081015151905151145b6105d05760405162461bcd60e51b81526004016101229061219d565b60c086015151516001101561064a5760015b60c0870151515181101561064857816001600160a01b03168760c0015160000151828151811061060e57fe5b602002602001015160e001516001600160a01b0316146106405760405162461bcd60e51b815260040161012290612353565b6001016105e2565b505b60c086015180516040820151602090920151610668929088866108b9565b6001546040516339d63abd60e21b81526001600160a01b039091169063e758eaf490610698908590600401612050565b600060405180830381600087803b1580156106b257600080fd5b505af11580156106c6573d6000803e3d6000fd5b50505050505050505050565b60005460ff16156106f55760405162461bcd60e51b815260040161012290612144565b60035460405163df7f453b60e01b815233916001600160a01b03169063df7f453b90610725908490600401612007565b60206040518083038186803b15801561073d57600080fd5b505afa158015610751573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506107759190810190611c0a565b6107915760405162461bcd60e51b81526004016101229061220b565b50600180546001600160a01b039586166001600160a01b031991821617825560028054958716958216959095179094556000805460048054948816949096169390931790945560ff199290941661010002610100600160a81b031990911617169091179055565b600080600080845160411461081357600093505050506108b3565b50505060208201516040830151606084015160001a601b81101561083557601b015b8060ff16601b1415801561084d57508060ff16601c14155b1561085e57600093505050506108b3565b600186828585604051600081526020016040526040516108819493929190612094565b6020604051602081039080840390855afa1580156108a3573d6000803e3d6000fd5b5050506020604051035193505050505b92915050565b60006108c786868686610930565b905080156108e0576108db86868585610a9e565b610928565b60005b86518110156109265761091e8782815181106108fb57fe5b602002602001015187838151811061090f57fe5b60200260200101518686610ae4565b6001016108e3565b505b505050505050565b6000808560008151811061094057fe5b60200260200101516101000151905060008660008151811061095e57fe5b602002602001015160000151905060008760008151811061097b57fe5b602002602001015160200151905060008090505b88518110156109e5576109dd8982815181106109a757fe5b60200260200101518983815181106109bb57fe5b6020026020010151888a85815181106109d057fe5b6020026020010151610b04565b60010161098f565b50600188511115610a8e5760015b8851811015610a8c57831515898281518110610a0b57fe5b602002602001015161010001511515141580610a3e575082898281518110610a2f57fe5b60200260200101516000015114155b80610a725750816001600160a01b0316898281518110610a5a57fe5b6020026020010151602001516001600160a01b031614155b15610a84576000945050505050610a96565b6001016109f3565b505b600193505050505b949350505050565b610aa66117d9565b610ab08585610c70565b9050610ad185600081518110610ac257fe5b60200260200101518285610ce6565b610add85858585610d01565b5050505050565b610aec6117d9565b610af68585610eb6565b9050610add85828585610f2b565b60008311610b245760405162461bcd60e51b81526004016101229061210d565b610b3584838363ffffffff61103216565b600480548551604051637d4b2a1960e01b81526001600160a01b0390921692637d4b2a1992610b65929101612050565b60206040518083038186803b158015610b7d57600080fd5b505afa158015610b91573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610bb59190810190611c26565b15610bd25760405162461bcd60e51b8152600401610122906120b2565b60015460405163a5f650d760e01b81526001600160a01b039091169063a5f650d790610c0490879087906004016124ed565b60206040518083038186803b158015610c1c57600080fd5b505afa158015610c30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610c549190810190611c0a565b61038d5760405162461bcd60e51b815260040161012290612327565b610c786117d9565b610c806117d9565b835160005b81811015610cdc57610c956117d9565b610cc5878381518110610ca457fe5b6020026020010151878481518110610cb857fe5b6020026020010151610eb6565b9050610cd18482611097565b935050600101610c85565b5090949350505050565b610cf1838383611109565b610cfc8383836112e3565b505050565b60005b8451811015610add57610d156117d9565b610d38868381518110610d2457fe5b6020026020010151868481518110610cb857fe5b60015487519192506000916001600160a01b039091169063c9f67f9c90899086908110610d6157fe5b602002602001015184600001516040518363ffffffff1660e01b8152600401610d8b9291906124ed565b602060405180830381600087803b158015610da557600080fd5b505af1158015610db9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610ddd9190810190611c26565b9050610dfc878481518110610dee57fe5b602002602001015183611323565b846001600160a01b0316878481518110610e1257fe5b602002602001015160000151888581518110610e2a57fe5b602002602001015160c001516001600160a01b03167f7fce7b83d2014c90bf64f0281296c1ecf7429a9473167b683f3f14c55bfe9e1f84610e7d8c8981518110610e7057fe5b602002602001015161133b565b898d8a81518110610e8a57fe5b602002602001015189604051610ea495949392919061250a565b60405180910390a45050600101610d04565b610ebe6117d9565b6000610ec8611398565b90506000610ef38560600151610ee784876113a590919063ffffffff16565b9063ffffffff6113d316565b90506000610f07828663ffffffff6113f516565b60408051606081018252968752602087019190915285019190915250919392505050565b600154835160405163327d9fe760e21b81526000926001600160a01b03169163c9f67f9c91610f5e9189916004016124ed565b602060405180830381600087803b158015610f7857600080fd5b505af1158015610f8c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610fb09190810190611c26565b9050610fbc8585611323565b610fc7858585610ce6565b826001600160a01b031685600001518660c001516001600160a01b03167f7fce7b83d2014c90bf64f0281296c1ecf7429a9473167b683f3f14c55bfe9e1f8461100f8a61133b565b878b8b60405161102395949392919061250a565b60405180910390a45050505050565b61103b8361140a565b61104583826114ba565b6110615760405162461bcd60e51b815260040161012290612171565b816001600160a01b03168360c001516001600160a01b03161415610cfc5760405162461bcd60e51b815260040161012290612383565b61109f6117d9565b60408051606081019091528251845182916110c0919063ffffffff6114fa16565b81526020016110e0846020015186602001516114fa90919063ffffffff16565b8152602001611100846040015186604001516114fa90919063ffffffff16565b90529392505050565b82610100015115611201576002805484516020860151604080870151905163c6b4931560e01b81526001600160a01b039094169463c6b4931594611154949392889291600401612059565b600060405180830381600087803b15801561116e57600080fd5b505af1158015611182573d6000803e3d6000fd5b50506002805486516020808901519088015160405163904e531b60e01b81526001600160a01b03909416965063904e531b95506111ca94929391928892909190600401612059565b600060405180830381600087803b1580156111e457600080fd5b505af11580156111f8573d6000803e3d6000fd5b50505050610cfc565b60025483516020850151604080860151905163c6b4931560e01b81526001600160a01b039094169363c6b493159361124493909290918791600191600401612059565b600060405180830381600087803b15801561125e57600080fd5b505af1158015611272573d6000803e3d6000fd5b505060025485516020808801519087015160405163904e531b60e01b81526001600160a01b03909416955063904e531b94506112b5938791600191600401612059565b600060405180830381600087803b1580156112cf57600080fd5b505af1158015610926573d6000803e3d6000fd5b602080840151600254918401516113079284916001600160a01b039091169061150c565b610cfc5760405162461bcd60e51b8152600401610122906123e3565b61132d82826115a2565b6113378282611786565b5050565b80516020808301516040808501516060860151608087015160a088015160c089015160e08a01516101008b0151965160009a61137b9a9099989101611f77565b604051602081830303815290604052805190602001209050919050565b68056bc75e2d6310000090565b6000826113b4575060006108b3565b828202828482816113c157fe5b04146113cc57600080fd5b9392505050565b60008082116113e157600080fd5b60008284816113ec57fe5b04949350505050565b60008282111561140457600080fd5b50900390565b600081604001511161142e5760405162461bcd60e51b8152600401610122906120e0565b6000816060015111801561144e575068056bc75e2d631000008160600151105b61146a5760405162461bcd60e51b8152600401610122906121d4565b60208101516001600160a01b03166114945760405162461bcd60e51b8152600401610122906122fb565b428160800151116114b75760405162461bcd60e51b8152600401610122906122d4565b50565b6000806114c68461133b565b90508360c001516001600160a01b03166114e86114e2836117c6565b856107f8565b6001600160a01b031614949350505050565b6000828201838110156113cc57600080fd5b60008054604051630aed65f560e11b81526101009091046001600160a01b0316906315dacbea9061154790889088908890889060040161201b565b602060405180830381600087803b15801561156157600080fd5b505af1158015611575573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506115999190810190611c0a565b95945050505050565b8161010001511561169f576002548251602084015160c0850151604080860151905163c6b4931560e01b81526001600160a01b039095169463c6b49315946115f69490939092909160019190600401612059565b600060405180830381600087803b15801561161057600080fd5b505af1158015611624573d6000803e3d6000fd5b50506002548451602086015160c0870151865160405163904e531b60e01b81526001600160a01b03909516965063904e531b95506116689460019190600401612059565b600060405180830381600087803b15801561168257600080fd5b505af1158015611696573d6000803e3d6000fd5b50505050611337565b600280548351602085015160c0860151604080870151905163c6b4931560e01b81526001600160a01b039095169563c6b49315956116e39594939290600401612059565b600060405180830381600087803b1580156116fd57600080fd5b505af1158015611711573d6000803e3d6000fd5b5050600280548551602087015160c0880151875160405163904e531b60e01b81526001600160a01b03909516975063904e531b965061175895939492939192600401612059565b600060405180830381600087803b15801561177257600080fd5b505af1158015610928573d6000803e3d6000fd5b602082015160c083015160025483516117aa9392916001600160a01b03169061150c565b6113375760405162461bcd60e51b8152600401610122906123e3565b60008160405160200161137b9190611fd6565b60405180606001604052806000815260200160008152602001600081525090565b80356108b38161258c565b600082601f830112611815578081fd5b81356118286118238261256c565b612545565b8181529150602080830190840160005b838110156118655761185087602084358901016119d9565b83526020928301929190910190600101611838565b5050505092915050565b600082601f83011261187f578081fd5b813561188d6118238261256c565b8181529150602080830190848101610120808502870183018810156118b157600080fd5b60005b858110156119595781838a0312156118cb57600080fd5b6118d482612545565b833581526118e48a8686016117fa565b8582015260408401356040820152606084013560608201526080840135608082015260a084013560a082015261191d8a60c086016117fa565b60c082015261192f8a60e086016117fa565b60e08201526101006119438b8287016119ce565b90820152855293830193918101916001016118b4565b50505050505092915050565b600082601f830112611975578081fd5b81356119836118238261256c565b8181529150602080830190848101818402860182018710156119a457600080fd5b60005b848110156119c3578135845292820192908201906001016119a7565b505050505092915050565b80356108b3816125a1565b600082601f8301126119e9578081fd5b813567ffffffffffffffff8111156119ff578182fd5b611a12601f8201601f1916602001612545565b9150808252836020828501011115611a2957600080fd5b8060208401602084013760009082016020015292915050565b600060e08284031215611a53578081fd5b611a5d60e0612545565b9050813567ffffffffffffffff80821115611a7757600080fd5b611a83858386016119d9565b83526020840135915080821115611a9957600080fd5b611aa5858386016119d9565b60208401526040840135915080821115611abe57600080fd5b611aca858386016119d9565b60408401526060840135915080821115611ae357600080fd5b611aef858386016119d9565b60608401526080840135915080821115611b0857600080fd5b611b14858386016119d9565b608084015260a0840135915080821115611b2d57600080fd5b611b39858386016119d9565b60a084015260c0840135915080821115611b5257600080fd5b50611b5f84828501611b6b565b60c08301525092915050565b600060808284031215611b7c578081fd5b611b866080612545565b9050813567ffffffffffffffff80821115611ba057600080fd5b611bac8583860161186f565b83526020840135915080821115611bc257600080fd5b611bce85838601611805565b60208401526040840135915080821115611be757600080fd5b50611bf484828501611965565b6040830152506060820135606082015292915050565b600060208284031215611c1b578081fd5b81516113cc816125a1565b600060208284031215611c37578081fd5b5051919050565b60008060008060808587031215611c53578283fd5b8435611c5e8161258c565b93506020850135611c6e8161258c565b92506040850135611c7e8161258c565b91506060850135611c8e8161258c565b939692955090935050565b60008060008060808587031215611cae578182fd5b843567ffffffffffffffff80821115611cc5578384fd5b611cd188838901611a42565b955060208701359150611ce38261258c565b90935060408601359080821115611cf8578384fd5b611d04888389016119d9565b93506060870135915080821115611d19578283fd5b50611d26878288016119d9565b91505092959194509250565b60008060408385031215611d44578182fd5b823567ffffffffffffffff80821115611d5b578384fd5b611d6786838701611a42565b93506020850135915080821115611d7c578283fd5b50611d89858286016119d9565b9150509250929050565b6000815180845260208401935060208301825b82811015611dc4578151865260209586019590910190600101611da6565b5093949350505050565b15159052565b60008151808452815b81811015611df957602081850181015186830182015201611ddd565b81811115611e0a5782602083870101525b50601f01601f19169290920160200192915050565b805160808084528151908401819052600091602091839160a08701919084015b81841015611e6857611e52838251611f0a565b6001939093019261012092909201918401611e3f565b50508483015186820387850152805180835285935082850191818602840186019086015b82861015611ebc57601f19858303018452611ea8828251611dd4565b600196909601959387019391508601611e8c565b506040880151955088810360408a0152611ed68187611d93565b94505050505060608401516060860152809250505092915050565b8051825260208082015190830152604090810151910152565b80518252602081015160018060a01b03808216602085015260408301516040850152606083015160608501526080830151608085015260a083015160a08501528060c08401511660c08501528060e08401511660e085015250506101008082015161038d82850182611dce565b9889526bffffffffffffffffffffffff19606098891b811660208b015260348a0197909752605489019590955260748801939093526094870191909152841b831660b486015290921b1660c8830152151560f81b60dc82015260dd0190565b7f19457468657265756d205369676e6564204d6573736167653a0a3332000000008152601c810191909152603c0190565b6001600160a01b0391909116815260200190565b6001600160a01b039485168152928416602084015292166040820152606081019190915260800190565b901515815260200190565b90815260200190565b8581526001600160a01b0385811660208301528416604082015260a081016003841061208157fe5b6060820193909352608001529392505050565b93845260ff9290921660208401526040830152606082015260800190565b6020808252601490820152734d41524b45545f4e4f545f545241444541424c4560601b604082015260600190565b602080825260139082015272544f54414c5f4245545f53495a455f5a45524f60681b604082015260600190565b60208082526019908201527f54414b45525f414d4f554e545f4e4f545f504f53495449564500000000000000604082015260600190565b6020808252601390820152721053149150511657d253925512505312569151606a1b604082015260600190565b6020808252601290820152710a6928e9c82a8aaa48abe9a92a69a82a886960731b604082015260600190565b60208082526017908201527f494e434f52524543545f41525241595f4c454e47544853000000000000000000604082015260600190565b60208082526017908201527f494e56414c49445f50455243454e544147455f4f444453000000000000000000604082015260600190565b6020808252601190820152702727aa2fa0afa9aaa822a92fa0a226a4a760791b604082015260600190565b6020808252601690820152751192531317d053149150511657d4d55093525515115160521b604082015260600190565b60208082526017908201527f53454e4445525f4d5553545f42455f4558454355544f52000000000000000000604082015260600190565b60208082526018908201527f54414b45525f5349474e41545552455f4d49534d415443480000000000000000604082015260600190565b6020808252600d908201526c13d491115497d1561412549151609a1b604082015260600190565b60208082526012908201527124a72b20a624a22fa120a9a2afaa27a5a2a760711b604082015260600190565b602080825260129082015271494e53554646494349454e545f535041434560701b604082015260600190565b602080825260169082015275494e434f4e53495354454e545f4558454355544f525360501b604082015260600190565b6020808252600f908201526e2a20a5a2a92fa727aa2fa6a0a5a2a960891b604082015260600190565b6020808252601b908201527f4558454355544f525f5349474e41545552455f4d49534d415443480000000000604082015260600190565b6020808252601c908201527f43414e4e4f545f5452414e534645525f54414b45525f455343524f5700000000604082015260600190565b600060208252825160e06020840152612437610100840182611dd4565b60208501519150601f19808583030160408601526124558284611dd4565b60408701519350818682030160608701526124708185611dd4565b925050606086015192508085830301608086015261248e8284611dd4565b60808701519350818682030160a08701526124a98185611dd4565b92505060a08601519250808583030160c08601526124c78284611dd4565b60c08701519350818682030160e08701526124e28185611e1f565b979650505050505050565b61014081016124fc8285611f0a565b826101208301529392505050565b85815260208101859052604081018490526101e0810161252d6060830185611f0a565b61253b610180830184611ef1565b9695505050505050565b60405181810167ffffffffffffffff8111828210171561256457600080fd5b604052919050565b600067ffffffffffffffff821115612582578081fd5b5060209081020190565b6001600160a01b03811681146114b757600080fd5b80151581146114b757600080fdfea365627a7a72315820af59bc471fef2ae8427d4dcfc1cce3d5f11d7b83e8d4a51016d4186688de536f6c6578706572696d656e74616cf564736f6c63430005100040
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000087d712688a706d4343704eeb382cb72abe76452e00000000000000000000000090c997f83885b4bd16d3ef8add73b9d901d49095
-----Decoded View---------------
Arg [0] : _superAdminRole (address): 0x87d712688a706d4343704eEB382CB72aBE76452e
Arg [1] : _eip712FillHasher (address): 0x90C997f83885B4Bd16D3ef8ADD73B9d901d49095
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 00000000000000000000000087d712688a706d4343704eeb382cb72abe76452e
Arg [1] : 00000000000000000000000090c997f83885b4bd16d3ef8add73b9d901d49095
Deployed Bytecode Sourcemap
350:9218:18:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;350:9218:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55:23:2;;;:::i;:::-;;;;;;;;;;;;;;;;833:1526:18;;;;;;;;;:::i;:::-;;2694:1792;;;;;;;;;:::i;1651:411:14:-;;;;;;;;;:::i;55:23:2:-;;;;;;:::o;833:1526:18:-;971:16;990:11;:17;;;:24;;;1015:1;990:27;;;;;;;;;;;;;;:36;;;971:55;;1036:16;1119:11;:17;;;:30;;;:37;1084:11;:17;;;:24;;;:31;:72;:157;;;;-1:-1:-1;1207:17:18;;;;:27;;;;:34;1172:24;;:31;:69;1084:157;1063:227;;;;-1:-1:-1;;;1063:227:18;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1305:22:18;;;1301:850;;1354:16;;:44;;-1:-1:-1;;;1354:44:18;;-1:-1:-1;;;;;1354:16:18;;;;:31;;:44;;1386:11;;1354:44;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1354:44:18;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;1354:44:18;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;1354:44:18;;;;;;;;;1438:5;;:36;;-1:-1:-1;;;1438:36:18;;1343:55;;-1:-1:-1;;;;;;1438:5:18;;:26;;:36;;1343:55;;1438:36;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;1438:36:18;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;1438:36:18;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;1438:36:18;;;;;;;;;:45;1413:126;;;;-1:-1:-1;;;1413:126:18;;;;;;;;;1677:8;-1:-1:-1;;;;;1579:106:18;:94;1614:8;1644:11;1579:13;:94::i;:::-;-1:-1:-1;;;;;1579:106:18;;1554:192;;;;-1:-1:-1;;;1554:192:18;;;;;;;;;1765:17;;;;:24;:31;1799:1;-1:-1:-1;1761:329:18;;;1837:1;1820:256;1844:17;;;;:24;:31;1840:35;;1820:256;;;1977:8;-1:-1:-1;;;;;1937:48:18;:11;:17;;;:24;;;1962:1;1937:27;;;;;;;;;;;;;;:36;;;-1:-1:-1;;;;;1937:48:18;;1904:153;;;;-1:-1:-1;;;1904:153:18;;;;;;;;;1877:3;;1820:256;;;;1761:329;2104:5;;:36;;-1:-1:-1;;;2104:36:18;;-1:-1:-1;;;;;2104:5:18;;;;:26;;:36;;2131:8;;2104:36;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;2104:36:18;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;2104:36:18;;;;1301:850;2186:17;;;;:24;;2224:30;;;;2268:27;;;;;2161:190;;2224:30;2309:10;2333:8;2161:11;:190::i;:::-;833:1526;;;;:::o;2694:1792::-;2909:16;;:44;;-1:-1:-1;;;2909:44:18;;2890:16;;-1:-1:-1;;;;;2909:16:18;;:31;;:44;;2941:11;;2909:44;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;2909:44:18;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;2909:44:18;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;2909:44:18;;;;;;;;;2890:63;;3068:5;-1:-1:-1;;;;;2985:88:18;:79;3016:8;3042;2985:13;:79::i;:::-;-1:-1:-1;;;;;2985:88:18;;2964:159;;;;-1:-1:-1;;;2964:159:18;;;;;;;;;3155:5;;:36;;-1:-1:-1;;;3155:36:18;;-1:-1:-1;;;;;3155:5:18;;;;:26;;:36;;3182:8;;3155:36;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;3155:36:18;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;3155:36:18;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;3155:36:18;;;;;;;;;:45;3134:114;;;;-1:-1:-1;;;3134:114:18;;;;;;;;;3259:16;3278:11;:17;;;:24;;;3303:1;3278:27;;;;;;;;;;;;;;:36;;;3259:55;;3349:1;-1:-1:-1;;;;;3329:22:18;:8;-1:-1:-1;;;;;3329:22:18;;3325:363;;3392:10;-1:-1:-1;;;;;3392:22:18;;;3367:104;;;;-1:-1:-1;;;3367:104:18;;;;;;;;;3608:8;-1:-1:-1;;;;;3510:106:18;:94;3545:8;3575:11;3510:13;:94::i;:::-;-1:-1:-1;;;;;3510:106:18;;3485:192;;;;-1:-1:-1;;;3485:192:18;;;;;;;;;3754:17;;;;:30;;;;:37;3719:24;;:31;:72;:157;;;;-1:-1:-1;3842:17:18;;;;:27;;;;:34;3807:24;;:31;:69;3719:157;3698:227;;;;-1:-1:-1;;;3698:227:18;;;;;;;;;3940:17;;;;:24;:31;3974:1;-1:-1:-1;3936:301:18;;;4008:1;3991:236;4015:17;;;;:24;:31;4011:35;;3991:236;;;4140:8;-1:-1:-1;;;;;4100:48:18;:11;:17;;;:24;;;4125:1;4100:27;;;;;;;;;;;;;;:36;;;-1:-1:-1;;;;;4100:48:18;;4071:141;;;;-1:-1:-1;;;4071:141:18;;;;;;;;;4048:3;;3991:236;;;;3936:301;4272:17;;;;:24;;4310:30;;;;4354:27;;;;;4247:185;;4310:30;4395:5;4414:8;4247:11;:185::i;:::-;4443:5;;:36;;-1:-1:-1;;;4443:36:18;;-1:-1:-1;;;;;4443:5:18;;;;:26;;:36;;4470:8;;4443:36;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;4443:36:18;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;4443:36:18;;;;2694:1792;;;;;;:::o;1651:411:14:-;200:11:2;;;;199:12;191:44;;;;-1:-1:-1;;;191:44:2;;;;;;;;;2250:14:14;;:37;;-1:-1:-1;;;2250:37:14;;1880:10;;-1:-1:-1;;;;;2250:14:14;;:27;;:37;;1880:10;;2250:37;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;2250:37:14;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;2250:37:14;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;2250:37:14;;;;;;;;;2229:101;;;;-1:-1:-1;;;2229:101:14;;;;;;;;;-1:-1:-1;1906:5:14;:14;;-1:-1:-1;;;;;1906:14:14;;;-1:-1:-1;;;;;;1906:14:14;;;;;;1930:6;:16;;;;;;;;;;;;;;;1906:5;1956:27;;1993:15;:34;;;;;;;;;;;;;;;;-1:-1:-1;;1956:27:14;;;;1906:14;1956:27;-1:-1:-1;;;;;;1956:27:14;;;;2037:18;;;;;;1651:411::o;609:1026:41:-;687:7;706:9;725;744:7;804:9;:16;824:2;804:22;800:72;;858:1;842:19;;;;;;;800:72;-1:-1:-1;;;1166:4:41;1151:20;;1145:27;1211:4;1196:20;;1190:27;1264:4;1249:20;;1243:27;1240:1;1235:36;1390:2;1386:6;;1382:44;;;1413:2;1408:7;1382:44;1503:1;:7;;1508:2;1503:7;;:18;;;;;1514:1;:7;;1519:2;1514:7;;1503:18;1499:130;;;1553:1;1537:19;;;;;;;1499:130;1594:24;1604:4;1610:1;1613;1616;1594:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;1594:24:41;;;;;;;;1587:31;;;;;609:1026;;;;;:::o;4951:922:18:-;5175:21;5199:127;5237:11;5262:12;5288:9;5311:5;5199:24;:127::i;:::-;5175:151;;5408:16;5404:463;;;5440:140;5476:11;5505:12;5535:5;5558:8;5440:18;:140::i;:::-;5404:463;;;5616:9;5611:246;5635:11;:18;5631:1;:22;5611:246;;;5678:164;5716:11;5728:1;5716:14;;;;;;;;;;;;;;5752:12;5765:1;5752:15;;;;;;;;;;;;;;5789:5;5816:8;5678:16;:164::i;:::-;5655:3;;5611:246;;;;5404:463;4951:922;;;;;;:::o;7202:1098::-;7429:4;7449:29;7481:11;7493:1;7481:14;;;;;;;;;;;;;;:39;;;7449:71;;7530:18;7551:11;7563:1;7551:14;;;;;;;;;;;;;;:25;;;7530:46;;7586:17;7606:11;7618:1;7606:14;;;;;;;;;;;;;;:24;;;7586:44;;7646:9;7658:1;7646:13;;7641:222;7665:11;:18;7661:1;:22;7641:222;;;7704:148;7738:11;7750:1;7738:14;;;;;;;;;;;;;;7770:12;7783:1;7770:15;;;;;;;;;;;;;;7803:5;7826:9;7836:1;7826:12;;;;;;;;;;;;;;7704:16;:148::i;:::-;7685:3;;7641:222;;;;7898:1;7877:11;:18;:22;7873:400;;;7932:1;7915:348;7939:11;:18;7935:1;:22;7915:348;;;8029:24;7986:67;;:11;7998:1;7986:14;;;;;;;;;;;;;;:39;;;:67;;;;:130;;;;8106:10;8077:11;8089:1;8077:14;;;;;;;;;;;;;;:25;;;:39;;7986:130;:191;;;;8168:9;-1:-1:-1;;;;;8140:37:18;:11;8152:1;8140:14;;;;;;;;;;;;;;:24;;;-1:-1:-1;;;;;8140:37:18;;;7986:191;7982:267;;;8225:5;8218:12;;;;;;;;7982:267;7959:3;;7915:348;;;;7873:400;8289:4;8282:11;;;;;7202:1098;;;;;;;:::o;6249:612::-;6446:53;;:::i;:::-;6502:101;6556:11;6581:12;6502:40;:101::i;:::-;6446:157;;6614:107;6647:11;6659:1;6647:14;;;;;;;;;;;;;;6675:17;6706:5;6614:19;:107::i;:::-;6732:122;6766:11;6791:12;6817:5;6836:8;6732:20;:122::i;:::-;6249:612;;;;;:::o;2620:448:14:-;2798:48;;:::i;:::-;2849:89;2898:5;2917:11;2849:35;:89::i;:::-;2798:140;;2949:112;2979:5;2998:12;3024:5;3043:8;2949:16;:112::i;5647:584::-;5878:1;5864:11;:15;5843:87;;;;-1:-1:-1;;;5843:87:14;;;;;;;;;5940:41;:5;5965;5972:8;5940:41;:24;:41;:::i;:::-;6012:15;;;6042:16;;6012:47;;-1:-1:-1;;;6012:47:14;;-1:-1:-1;;;;;6012:15:14;;;;:29;;:47;;6042:16;6012:47;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;6012:47:14;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;6012:47:14;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;6012:47:14;;;;;;;;;:52;5991:119;;;;-1:-1:-1;;;5991:119:14;;;;;;;;;6141:5;;:39;;-1:-1:-1;;;6141:39:14;;-1:-1:-1;;;;;6141:5:14;;;;:19;;:39;;6161:5;;6168:11;;6141:39;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;6141:39:14;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;6141:39:14;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;6141:39:14;;;;;;;;;6120:104;;;;-1:-1:-1;;;6120:104:14;;;;;;;;2429:700:37;2600:35;;:::i;:::-;2651:56;;:::i;:::-;2745:18;;2717:25;2773:313;2797:17;2793:1;:21;2773:313;;;2835:48;;:::i;:::-;2886:98;2923:11;2935:1;2923:14;;;;;;;;;;;;;;2955:12;2968:1;2955:15;;;;;;;;;;;;;;2886:19;:98::i;:::-;2835:149;;3021:54;3040:20;3062:12;3021:18;:54::i;:::-;2998:77;-1:-1:-1;;2816:3:37;;2773:313;;;-1:-1:-1;3102:20:37;;2429:700;-1:-1:-1;;;;2429:700:37:o;4939:395:14:-;5123:96;5159:5;5178:12;5204:5;5123:22;:96::i;:::-;5230:97;5267:5;5286:12;5312:5;5230:23;:97::i;:::-;4939:395;;;:::o;8608:958:18:-;8812:9;8807:753;8831:11;:18;8827:1;:22;8807:753;;;8870:48;;:::i;:::-;8921:114;8974:11;8986:1;8974:14;;;;;;;;;;;;;;9006:12;9019:1;9006:15;;;;;;;8921:114;9074:5;;9085:14;;8870:165;;-1:-1:-1;9050:21:18;;-1:-1:-1;;;;;9074:5:18;;;;:10;;9085:11;;9097:1;;9085:14;;;;;;;;;;;;9101:12;:24;;;9074:52;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;9074:52:18;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;9074:52:18;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;9074:52:18;;;;;;;;;9050:76;;9141:95;9178:11;9190:1;9178:14;;;;;;;;;;;;;;9210:12;9141:19;:95::i;:::-;9364:5;-1:-1:-1;;;;;9256:293:18;9321:11;9333:1;9321:14;;;;;;;;;;;;;;:25;;;9283:11;9295:1;9283:14;;;;;;;;;;;;;;:20;;;-1:-1:-1;;;;;9256:293:18;;9387:13;9418:29;:11;9430:1;9418:14;;;;;;;;;;;;;;:27;:29::i;:::-;9465:8;9491:11;9503:1;9491:14;;;;;;;;;;;;;;9523:12;9256:293;;;;;;;;;;;;;;;;;;;-1:-1:-1;;8851:3:18;;8807:753;;795:561:37;943:35;;:::i;:::-;994:21;1018:27;:25;:27::i;:::-;994:51;;1055:15;1073:56;1108:5;:20;;;1073:30;1089:13;1073:11;:15;;:30;;;;:::i;:::-;:34;:56;:34;:56;:::i;:::-;1055:74;-1:-1:-1;1139:19:37;1161:24;1055:74;1173:11;1161:24;:11;:24;:::i;:::-;1203:146;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1203:146:37;;795:561;-1:-1:-1;;;795:561:37:o;3421:707:14:-;3652:5;;3670:24;;3652:43;;-1:-1:-1;;;3652:43:14;;3628:21;;-1:-1:-1;;;;;3652:5:14;;:10;;:43;;3663:5;;3652:43;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;3652:43:14;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;3652:43:14;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;3652:43:14;;;;;;;;;3628:67;;3706:74;3739:5;3758:12;3706:19;:74::i;:::-;3791:93;3824:5;3843:12;3869:5;3791:19;:93::i;:::-;3978:5;-1:-1:-1;;;;;3900:221:14;3948:5;:16;;;3923:5;:11;;;-1:-1:-1;;;;;3900:221:14;;3997:13;4024:20;:5;:18;:20::i;:::-;4058:8;4080:5;4099:12;3900:221;;;;;;;;;;;;;;;;;;;3421:707;;;;;:::o;3231:305:36:-;3341:24;3359:5;3341:17;:24::i;:::-;3396:31;3411:5;3418:8;3396:14;:31::i;:::-;3375:96;;;;-1:-1:-1;;;3375:96:36;;;;;;;;;3504:5;-1:-1:-1;;;;;3489:20:36;:5;:11;;;-1:-1:-1;;;;;3489:20:36;;;3481:48;;;;-1:-1:-1;;;3481:48:36;;;;;;;;1604:533:37;1801:35;;:::i;:::-;1859:271;;;;;;;;;1944:24;;1915;;1859:271;;1915:54;;:24;:54;:28;:54;:::i;:::-;1859:271;;;;1996:54;2025:12;:24;;;1996:12;:24;;;:28;;:54;;;;:::i;:::-;1859:271;;;;2073:46;2098:12;:20;;;2073:12;:20;;;:24;;:46;;;;:::i;:::-;1859:271;;1852:278;1604:533;-1:-1:-1;;;1604:533:37:o;7034:1184:14:-;7224:5;:30;;;7220:992;;;7270:6;;;7315:16;;7349:15;;;;7453:20;;;;;7270:217;;-1:-1:-1;;;7270:217:14;;-1:-1:-1;;;;;7270:6:14;;;;:27;;:217;;7315:16;7349:15;7382:5;;7270:6;:217;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;7270:217:14;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;7501:6:14;;;7544:16;;7578:15;;;;;7682:24;;;;7501:219;;-1:-1:-1;;;7501:219:14;;-1:-1:-1;;;;;7501:6:14;;;;-1:-1:-1;7501:25:14;;-1:-1:-1;7501:219:14;;7544:16;;7578:15;;7611:5;;7501:6;;7682:24;7501:219;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;7501:219:14;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;7501:219:14;;;;7220:992;;;7751:6;;7796:16;;7830:15;;;;7934:20;;;;;7751:217;;-1:-1:-1;;;7751:217:14;;-1:-1:-1;;;;;7751:6:14;;;;:27;;:217;;7796:16;;7830:15;;7863:5;;7751:6;;:217;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;7751:217:14;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;7982:6:14;;8025:16;;8059:15;;;;;8163:24;;;;7982:219;;-1:-1:-1;;;7982:219:14;;-1:-1:-1;;;;;7982:6:14;;;;-1:-1:-1;7982:25:14;;-1:-1:-1;7982:219:14;;8092:5;;7982:6;;:219;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;7982:219:14;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;10511:430:14;10753:15;;;;;10817:6;;10842:24;;;;10719:161;;10786:5;;-1:-1:-1;;;;;10817:6:14;;;;10719:16;:161::i;:::-;10698:236;;;;-1:-1:-1;;;10698:236:14;;;;;;;;4343:334;4504:77;4540:5;4559:12;4504:22;:77::i;:::-;4592:78;4629:5;4648:12;4592:23;:78::i;:::-;4343:334;;:::o;4107:469:36:-;4255:16;;4289:15;;;;;4322:18;;;;;4358:20;;;;4396:12;;;;4426:10;;;;4454:11;;;;4483:14;;;;4515:30;;;;4221:338;;4172:7;;4221:338;;4255:16;;4289:15;4515:30;4221:338;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;4221:338:36;;;4198:371;;;;;;4191:378;;4107:469;;;:::o;4582:98::-;441:6;4582:98;:::o;229:421:42:-;287:7;527:6;523:45;;-1:-1:-1;556:1:42;549:8;;523:45;590:5;;;594:1;590;:5;:1;613:5;;;;;:10;605:19;;;;;;642:1;229:421;-1:-1:-1;;;229:421:42:o;778:296::-;836:7;933:1;929;:5;921:14;;;;;;945:9;961:1;957;:5;;;;;;;778:296;-1:-1:-1;;;;778:296:42:o;1205:145::-;1263:7;1295:1;1290;:6;;1282:15;;;;;;-1:-1:-1;1319:5:42;;;1205:145::o;2486:435:36:-;2599:1;2578:5;:18;;;:22;2557:88;;;;-1:-1:-1;;;2557:88:36;;;;;;;;;2699:1;2676:5;:20;;;:24;:65;;;;;441:6;2704:5;:20;;;:37;2676:65;2655:135;;;;-1:-1:-1;;;2655:135:36;;;;;;;;;2808:15;;;;-1:-1:-1;;;;;2808:29:36;2800:60;;;;-1:-1:-1;;;2800:60:36;;;;;;;;;2893:3;2878:5;:12;;;:18;2870:44;;;;-1:-1:-1;;;2870:44:36;;;;;;;;;2486:435;:::o;2072:276::-;2186:4;2206:17;2226:19;2239:5;2226:12;:19::i;:::-;2206:39;;2330:5;:11;;;-1:-1:-1;;;;;2262:79:36;:64;2276:39;2305:9;2276:28;:39::i;:::-;2317:8;2262:13;:64::i;:::-;-1:-1:-1;;;;;2262:79:36;;;2072:276;-1:-1:-1;;;;2072:276:36:o;1431:145:42:-;1489:7;1520:5;;;1543:6;;;;1535:15;;;;;6557:230:14;6711:4;6738:5;;:42;;-1:-1:-1;;;6738:42:14;;:5;;;;-1:-1:-1;;;;;6738:5:14;;:18;;:42;;6757:5;;6764:4;;6770:2;;6774:5;;6738:42;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;6738:42:14;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;6738:42:14;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;6738:42:14;;;;;;;;;6731:49;6557:230;-1:-1:-1;;;;;6557:230:14:o;8419:1185::-;8586:5;:30;;;8582:1016;;;8632:6;;8677:16;;8711:15;;;;8744:11;;;;8821:20;;;;;8632:223;;-1:-1:-1;;;8632:223:14;;-1:-1:-1;;;;;8632:6:14;;;;:27;;:223;;8677:16;;8711:15;;8744:11;;8632:6;;8821:20;8632:223;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;8632:223:14;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;8869:6:14;;8912:16;;8946:15;;;;8979:11;;;;9056:24;;8869:225;;-1:-1:-1;;;8869:225:14;;-1:-1:-1;;;;;8869:6:14;;;;-1:-1:-1;8869:25:14;;-1:-1:-1;8869:225:14;;:6;;9056:24;8869:225;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;8869:225:14;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;8869:225:14;;;;8582:1016;;;9125:6;;;9170:16;;9204:15;;;;9237:11;;;;9314:20;;;;;9125:223;;-1:-1:-1;;;9125:223:14;;-1:-1:-1;;;;;9125:6:14;;;;:27;;:223;;9170:16;9204:15;9237:11;9314:20;9125:223;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;9125:223:14;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;9362:6:14;;;9405:16;;9439:15;;;;9472:11;;;;9549:24;;9362:225;;-1:-1:-1;;;9362:225:14;;-1:-1:-1;;;;;9362:6:14;;;;-1:-1:-1;9362:25:14;;-1:-1:-1;9362:225:14;;9405:16;;9439:15;;9472:11;;9362:225;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;9362:225:14;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;9828:413:14;10047:15;;;;10080:11;;;;10117:6;;10142:24;;10013:167;;10047:15;10080:11;-1:-1:-1;;;;;10117:6:14;;10013:16;:167::i;:::-;9992:242;;;;-1:-1:-1;;;9992:242:14;;;;;;;;1785:265:41;1854:7;2037:4;1984:58;;;;;;;;;350:9218:18;;;;;;;;;;;;;;;;;;;;;;;;:::o;5:130:-1:-;72:20;;97:33;72:20;97:33;;158:685;;276:3;269:4;261:6;257:17;253:27;243:2;;-1:-1;;284:12;243:2;331:6;318:20;353:81;368:65;426:6;368:65;;;353:81;;;462:21;;;344:90;-1:-1;506:4;519:14;;;;494:17;;614:1;599:238;624:6;621:1;618:13;599:238;;;731:42;769:3;506:4;707:3;694:17;498:6;682:30;;731:42;;;719:55;;506:4;788:14;;;;816;;;;;646:1;639:9;599:238;;;603:14;;;;236:607;;;;;883:760;;1015:3;1008:4;1000:6;996:17;992:27;982:2;;-1:-1;;1023:12;982:2;1070:6;1057:20;1092:95;1107:79;1179:6;1107:79;;1092:95;1215:21;;;1083:104;-1:-1;1259:4;1272:14;;;;1247:17;;;1373:6;1361:19;;;1352:29;;;;1349:38;-1:-1;1346:2;;;1400:1;;1390:12;1346:2;1425:1;1410:227;1435:6;1432:1;1429:13;1410:227;;;1373:6;8162:9;8157:3;8153:19;8149:32;8146:2;;;1425:1;;8184:12;8146:2;8212:22;1373:6;8212:22;;;8343;2709:20;8304:16;8297:75;8471:49;8516:3;1259:4;8496:9;8492:22;8471:49;;;1259:4;8457:5;8453:16;8446:75;8590:2;8648:9;8644:22;9673:20;8590:2;8609:5;8605:16;8598:75;8744:2;8802:9;8798:22;9673:20;8744:2;8763:5;8759:16;8752:75;8890:3;8949:9;8945:22;9673:20;8890:3;8910:5;8906:16;8899:75;9035:3;9094:9;9090:22;9673:20;9035:3;9055:5;9051:16;9044:75;9215:49;9260:3;9181;9240:9;9236:22;9215:49;;;9181:3;9201:5;9197:16;9190:75;9364:49;9409:3;9330;9389:9;9385:22;9364:49;;;9330:3;9350:5;9346:16;9339:75;9495:3;9531:46;9573:3;9495;9553:9;9549:22;9531:46;;;9511:18;;;9504:74;1503:69;;1586:14;;;;1614:16;;;;1457:1;1450:9;1410:227;;;1414:14;;;;;;975:668;;;;;1669:699;;1782:3;1775:4;1767:6;1763:17;1759:27;1749:2;;-1:-1;;1790:12;1749:2;1837:6;1824:20;1859:76;1874:60;1927:6;1874:60;;1859:76;1963:21;;;1850:85;-1:-1;2007:4;2020:14;;;;1995:17;;;2109;;;2100:27;;;;2097:36;-1:-1;2094:2;;;2146:1;;2136:12;2094:2;2171:1;2156:206;2181:6;2178:1;2175:13;2156:206;;;9673:20;;2249:50;;2313:14;;;;2341;;;;2203:1;2196:9;2156:206;;;2160:14;;;;;1742:626;;;;;2376:124;2440:20;;2465:30;2440:20;2465:30;;2921:432;;3018:3;3011:4;3003:6;2999:17;2995:27;2985:2;;-1:-1;;3026:12;2985:2;3073:6;3060:20;49885:18;49877:6;49874:30;49871:2;;;-1:-1;;49907:12;49871:2;3095:60;49980:9;49961:17;;-1:-1;;49957:33;50048:4;50038:15;3095:60;;;3086:69;;3175:6;3168:5;3161:21;3279:3;50048:4;3270:6;3203;3261:16;;3258:25;3255:2;;;3296:1;;3286:12;3255:2;54859:6;50048:4;3203:6;3199:17;50048:4;3237:5;3233:16;54836:30;54915:1;54897:16;;;50048:4;54897:16;54890:27;3237:5;2978:375;-1:-1;;2978:375;5003:1870;;5121:4;5109:9;5104:3;5100:19;5096:30;5093:2;;;-1:-1;;5129:12;5093:2;5157:20;5121:4;5157:20;;;5148:29;;5242:17;5229:31;5280:18;;5272:6;5269:30;5266:2;;;5257:1;;5302:12;5266:2;5347:55;5398:3;5389:6;5378:9;5374:22;5347:55;;;5329:16;5322:81;5494:2;5483:9;5479:18;5466:32;5452:46;;5280:18;5510:6;5507:30;5504:2;;;5257:1;;5540:12;5504:2;5585:55;5636:3;5627:6;5616:9;5612:22;5585:55;;;5494:2;5571:5;5567:16;5560:81;5733:2;5722:9;5718:18;5705:32;5691:46;;5280:18;5749:6;5746:30;5743:2;;;5257:1;;5779:12;5743:2;5824:55;5875:3;5866:6;5855:9;5851:22;5824:55;;;5733:2;5810:5;5806:16;5799:81;5970:2;5959:9;5955:18;5942:32;5928:46;;5280:18;5986:6;5983:30;5980:2;;;5257:1;;6016:12;5980:2;6061:55;6112:3;6103:6;6092:9;6088:22;6061:55;;;5970:2;6047:5;6043:16;6036:81;6206:3;6195:9;6191:19;6178:33;6164:47;;5280:18;6223:6;6220:30;6217:2;;;5257:1;;6253:12;6217:2;6298:55;6349:3;6340:6;6329:9;6325:22;6298:55;;;6206:3;6284:5;6280:16;6273:81;6448:3;6437:9;6433:19;6420:33;6406:47;;5280:18;6465:6;6462:30;6459:2;;;5257:1;;6495:12;6459:2;6540:55;6591:3;6582:6;6571:9;6567:22;6540:55;;;6448:3;6526:5;6522:16;6515:81;6686:3;6675:9;6671:19;6658:33;6644:47;;5280:18;6703:6;6700:30;6697:2;;;5257:1;;6733:12;6697:2;;6778:73;6847:3;6838:6;6827:9;6823:22;6778:73;;;6686:3;6764:5;6760:16;6753:99;;5087:1786;;;;;6913:1118;;7026:4;7014:9;7009:3;7005:19;7001:30;6998:2;;;-1:-1;;7034:12;6998:2;7062:20;7026:4;7062:20;;;7053:29;;7147:17;7134:31;7185:18;;7177:6;7174:30;7171:2;;;7162:1;;7207:12;7171:2;7252:89;7337:3;7328:6;7317:9;7313:22;7252:89;;;7234:16;7227:115;7436:2;7425:9;7421:18;7408:32;7394:46;;7185:18;7452:6;7449:30;7446:2;;;7162:1;;7482:12;7446:2;7527:75;7598:3;7589:6;7578:9;7574:22;7527:75;;;7436:2;7513:5;7509:16;7502:101;7700:2;7689:9;7685:18;7672:32;7658:46;;7185:18;7716:6;7713:30;7710:2;;;7162:1;;7746:12;7710:2;;7791:70;7857:3;7848:6;7837:9;7833:22;7791:70;;;7700:2;7777:5;7773:16;7766:96;;7927:2;7985:9;7981:22;9673:20;7927:2;7946:5;7942:16;7935:75;6992:1039;;;;;9884:257;;9996:2;9984:9;9975:7;9971:23;9967:32;9964:2;;;-1:-1;;10002:12;9964:2;2588:6;2582:13;2600:30;2624:5;2600:30;;10148:263;;10263:2;10251:9;10242:7;10238:23;10234:32;10231:2;;;-1:-1;;10269:12;10231:2;-1:-1;2857:13;;10225:186;-1:-1;10225:186;10418:785;;;;;10657:3;10645:9;10636:7;10632:23;10628:33;10625:2;;;-1:-1;;10664:12;10625:2;4074:6;4061:20;4086:48;4128:5;4086:48;;;10716:78;-1:-1;10831:2;10886:22;;3893:20;3918:49;3893:20;3918:49;;;10839:79;-1:-1;10955:2;11022:22;;4428:20;4453:61;4428:20;4453:61;;;10963:91;-1:-1;11091:2;11155:22;;4238:20;4263:58;4238:20;4263:58;;;10619:584;;;;-1:-1;10619:584;;-1:-1;;10619:584;11210:969;;;;;11412:3;11400:9;11391:7;11387:23;11383:33;11380:2;;;-1:-1;;11419:12;11380:2;11477:17;11464:31;11515:18;;11507:6;11504:30;11501:2;;;-1:-1;;11537:12;11501:2;11567:82;11641:7;11632:6;11621:9;11617:22;11567:82;;;11557:92;;11686:2;11729:9;11725:22;72:20;63:29;;97:33;124:5;97:33;;;11694:63;;-1:-1;11822:2;11807:18;;11794:32;;11835:30;;;11832:2;;;-1:-1;;11868:12;11832:2;11898:62;11952:7;11943:6;11932:9;11928:22;11898:62;;;11888:72;;12025:2;12014:9;12010:18;11997:32;11983:46;;11515:18;12041:6;12038:30;12035:2;;;-1:-1;;12071:12;12035:2;;12101:62;12155:7;12146:6;12135:9;12131:22;12101:62;;;12091:72;;;11374:805;;;;;;;;12186:614;;;12345:2;12333:9;12324:7;12320:23;12316:32;12313:2;;;-1:-1;;12351:12;12313:2;12409:17;12396:31;12447:18;;12439:6;12436:30;12433:2;;;-1:-1;;12469:12;12433:2;12499:82;12573:7;12564:6;12553:9;12549:22;12499:82;;;12489:92;;12646:2;12635:9;12631:18;12618:32;12604:46;;12447:18;12662:6;12659:30;12656:2;;;-1:-1;;12692:12;12656:2;;12722:62;12776:7;12767:6;12756:9;12752:22;12722:62;;;12712:72;;;12307:493;;;;;;15889:654;;16064:5;51313:12;52385:6;52380:3;52373:19;52422:4;52417:3;52413:14;16076:83;;52422:4;16226:5;50839:14;-1:-1;16265:256;16290:6;16287:1;16284:13;16265:256;;;16351:13;;16971:37;;52422:4;13681:14;;;;51992;;;;16312:1;16305:9;16265:256;;;-1:-1;16527:10;;15999:544;-1:-1;;;;15999:544;16551:94;53627:13;53620:21;16606:34;;16600:45;17299:315;;17423:5;51313:12;52385:6;52380:3;52373:19;-1:-1;55004:101;55018:6;55015:1;55012:13;55004:101;;;52422:4;55085:11;;;;;55079:18;55066:11;;;;;55059:39;55033:10;55004:101;;;55120:6;55117:1;55114:13;55111:2;;;-1:-1;52422:4;55176:6;52417:3;55167:16;;55160:27;55111:2;-1:-1;49980:9;55828:14;-1:-1;;55824:28;17570:39;;;;52422:4;17570:39;;17375:239;-1:-1;;17375:239;26407:1168;26618:23;;26550:4;26654:38;;;51313:12;;26541:14;;;52373:19;;;26407:1168;;52422:4;;26407:1168;;52413:14;;;;51313:12;50839:14;;15515:313;15540:6;15537:1;15534:13;15515:313;;;13389:88;13473:3;15607:6;15601:13;13389:88;;;15562:1;15555:9;;;;;13506:6;13497:16;;;;;51992:14;;15515:313;;;-1:-1;;26923:16;;;26917:23;26976:14;;;26960;;;26953:38;51313:12;;52373:19;;;-1:-1;;;52413:14;;;;14468:17;;;14459:27;;;;;50839:14;;14597:341;14622:6;14619:1;14616:13;14597:341;;;49980:9;;52417:3;14678:4;14674:20;;14669:3;14662:33;13189:60;13245:3;14729:6;14723:13;13189:60;;;15562:1;14637:9;;;;;14917:14;;;;14743:82;-1:-1;51992:14;;14597:341;;;14601:14;27208:4;27201:5;27197:16;27191:23;27171:43;;27260:3;27254:4;27250:14;27208:4;27238:3;27234:14;27227:38;27280:99;27374:4;27360:12;27280:99;;;27272:107;;;;;;27468:4;27461:5;27457:16;27451:23;27468:4;27532:3;27528:14;16971:37;27559:11;;;;;26523:1052;;;;;27663:657;27889:23;;16971:37;;28067:4;28056:16;;;28050:23;28127:14;;;16971:37;28224:4;28213:16;;;28207:23;28284:14;;16971:37;27789:531;28380:1606;28599:16;28593:23;16978:3;16971:37;28769:4;28762:5;28758:16;28752:23;49885:18;;54418:42;;;;54411:5;54407:54;28769:4;28833:3;28829:14;13770:37;28931:4;28924:5;28920:16;28914:23;28931:4;28995:3;28991:14;16971:37;29095:4;29088:5;29084:16;29078:23;29095:4;29159:3;29155:14;16971:37;29251:4;29244:5;29240:16;29234:23;29251:4;29315:3;29311:14;16971:37;29405:4;29398:5;29394:16;29388:23;29405:4;29469:3;29465:14;16971:37;54418:42;29560:4;29553:5;29549:16;29543:23;54407:54;29560:4;29624:3;29620:14;13770:37;54418:42;29718:4;29711:5;29707:16;29701:23;54407:54;29718:4;29782:3;29778:14;13770:37;;;29892:6;;29885:5;29881:18;29875:25;29906:59;29892:6;29952:3;29948:16;29934:12;29906:59;;33810:1343;16971:37;;;-1:-1;;56043:2;56039:14;;;;;34244:2;34235:12;;14028:58;34346:12;;;16971:37;;;;34457:12;;;16971:37;;;;34568:12;;;16971:37;;;;34679:12;;;16971:37;;;;56039:14;;;;34790:12;;;14028:58;56039:14;;;;34901:12;;;14028:58;53627:13;53620:21;55940:3;55936:15;35012:12;;;16846:52;35117:11;;;34135:1018;35160:511;19054:66;19034:87;;19018:2;19140:12;;16971:37;;;;35634:12;;;35368:303;35678:213;-1:-1;;;;;54407:54;;;;13770:37;;35796:2;35781:18;;35767:124;35898:547;-1:-1;;;;;54407:54;;;13770:37;;54407:54;;;36265:2;36250:18;;13770:37;54407:54;;36348:2;36333:18;;13770:37;36431:2;36416:18;;16971:37;;;;36100:3;36085:19;;36071:374;36452:201;53627:13;;53620:21;16606:34;;36564:2;36549:18;;36535:118;36660:213;16971:37;;;36778:2;36763:18;;36749:124;36880:679;16971:37;;;-1:-1;;;;;54407:54;;;37285:2;37270:18;;13770:37;54407:54;;37368:2;37353:18;;13770:37;37120:3;37105:19;;56152:1;56142:12;;56132:2;;56158:9;56132:2;37461;37446:18;;17702:60;;;;37544:3;37529:19;16971:37;37091:468;;-1:-1;;;37091:468;37566:539;16971:37;;;54623:4;54612:16;;;;37925:2;37910:18;;33763:35;38008:2;37993:18;;16971:37;38091:2;38076:18;;16971:37;37764:3;37749:19;;37735:370;38112:407;38303:2;38317:47;;;18325:2;38288:18;;;52373:19;-1:-1;;;52413:14;;;18341:43;18403:12;;;38274:245;38526:407;38717:2;38731:47;;;18654:2;38702:18;;;52373:19;-1:-1;;;52413:14;;;18670:42;18731:12;;;38688:245;38940:407;39131:2;39145:47;;;19391:2;39116:18;;;52373:19;19427:27;52413:14;;;19407:48;19474:12;;;39102:245;39354:407;39545:2;39559:47;;;19725:2;39530:18;;;52373:19;-1:-1;;;52413:14;;;19741:42;19802:12;;;39516:245;39768:407;39959:2;39973:47;;;20053:2;39944:18;;;52373:19;-1:-1;;;52413:14;;;20069:41;20129:12;;;39930:245;40182:407;40373:2;40387:47;;;20380:2;40358:18;;;52373:19;20416:25;52413:14;;;20396:46;20461:12;;;40344:245;40596:407;40787:2;40801:47;;;20712:2;40772:18;;;52373:19;20748:25;52413:14;;;20728:46;20793:12;;;40758:245;41010:407;41201:2;41215:47;;;21044:2;41186:18;;;52373:19;-1:-1;;;52413:14;;;21060:40;21119:12;;;41172:245;41424:407;41615:2;41629:47;;;21370:2;41600:18;;;52373:19;-1:-1;;;52413:14;;;21386:45;21450:12;;;41586:245;41838:407;42029:2;42043:47;;;21701:2;42014:18;;;52373:19;21737:25;52413:14;;;21717:46;21782:12;;;42000:245;42252:407;42443:2;42457:47;;;22033:2;42428:18;;;52373:19;22069:26;52413:14;;;22049:47;22115:12;;;42414:245;42666:407;42857:2;42871:47;;;22366:2;42842:18;;;52373:19;-1:-1;;;52413:14;;;22382:36;22437:12;;;42828:245;43080:407;43271:2;43285:47;;;22688:2;43256:18;;;52373:19;-1:-1;;;52413:14;;;22704:41;22764:12;;;43242:245;43494:407;43685:2;43699:47;;;23015:2;43670:18;;;52373:19;-1:-1;;;52413:14;;;23031:41;23091:12;;;43656:245;43908:407;44099:2;44113:47;;;23342:2;44084:18;;;52373:19;-1:-1;;;52413:14;;;23358:45;23422:12;;;44070:245;44322:407;44513:2;44527:47;;;23673:2;44498:18;;;52373:19;-1:-1;;;52413:14;;;23689:38;23746:12;;;44484:245;44736:407;44927:2;44941:47;;;23997:2;44912:18;;;52373:19;24033:29;52413:14;;;24013:50;24082:12;;;44898:245;45150:407;45341:2;45355:47;;;24333:2;45326:18;;;52373:19;24369:30;52413:14;;;24349:51;24419:12;;;45312:245;45564:377;;45740:2;45761:17;45754:47;24743:16;24737:23;24669:4;45740:2;45729:9;45725:18;24773:38;24826:69;24660:14;45729:9;24660:14;24876:12;24826:69;;;45740:2;24975:5;24971:16;24965:23;24945:43;;49980:9;;25024:14;45729:9;25028:4;25024:14;;25008;45729:9;25008:14;25001:38;25054:69;25118:4;25104:12;25054:69;;;25008:14;25204:5;25200:16;25194:23;25174:43;;25024:14;45729:9;25257:4;25253:14;;25237;45729:9;25237:14;25230:38;25283:69;25347:4;25333:12;25283:69;;;25275:77;;;25237:14;25431:5;25427:16;25421:23;25401:43;;25024:14;45729:9;25484:4;25480:14;;25464;45729:9;25464:14;25457:38;25510:69;25574:4;25560:12;25510:69;;;25464:14;25657:5;25653:16;25647:23;25627:43;;25024:14;45729:9;25710:4;25706:14;;25690;45729:9;25690:14;25683:38;25736:69;25800:4;25786:12;25736:69;;;25728:77;;;25690:14;25888:5;25884:16;25878:23;25858:43;;25024:14;45729:9;25941:4;25937:14;;25921;45729:9;25921:14;25914:38;25967:69;26031:4;26017:12;25967:69;;;25921:14;26115:5;26111:16;26105:23;26085:43;;25024:14;45729:9;26168:4;26164:14;;24669:4;45729:9;26148:14;26141:38;26194:105;26294:4;26280:12;26194:105;;;45807:124;45711:230;-1:-1;;;;;;;45711:230;45948:418;46140:3;46125:19;;46155:117;46129:9;46245:6;46155:117;;;17001:5;46351:3;46340:9;46336:19;16971:37;46111:255;;;;;;46790:871;16971:37;;;47291:2;47276:18;;16971:37;;;47374:2;47359:18;;16971:37;;;47126:3;47111:19;;47389:118;47503:2;47488:18;;47479:6;47389:118;;;47518:133;47646:3;47635:9;47631:19;47622:6;47518:133;;;47097:564;;;;;;;;;48538:256;48600:2;48594:9;48626:17;;;48701:18;48686:34;;48722:22;;;48683:62;48680:2;;;48758:1;;48748:12;48680:2;48600;48767:22;48578:216;;-1:-1;48578:216;48801:305;;48961:18;48953:6;48950:30;48947:2;;;-1:-1;;48983:12;48947:2;-1:-1;49028:4;49016:17;;;49081:15;;48884:222;56181:117;-1:-1;;;;;54407:54;;56240:35;;56230:2;;56289:1;;56279:12;56305:111;56386:5;53627:13;53620:21;56364:5;56361:32;56351:2;;56407:1;;56397:12
Swarm Source
bzzr://af59bc471fef2ae8427d4dcfc1cce3d5f11d7b83e8d4a51016d4186688de536f
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.